C , старые добрые ошибки LNK1169 (и LNK2005)

#c #compiler-errors #lnk

#c #ошибки компилятора #lnk

Вопрос:

У меня есть 4 файла, 2 заголовка и 2 файла cpp.

Файл заголовка один:

 #ifndef complex_2
#define complex_2
#include<iostream>
#include<cmath>

using namespace std;

namespace comp
{
    class complex{
    protected:
        double re, im;
    public:
        complex(){re = im = 0;}
        complex(double re_in, double im_in){
            re = re_in;
            im = im_in;
        }
        ~complex(){}

        void set_re(double re_in){
            re = re_in;
        }
        void set_im(double im_in){
            im = im_in;
        }
        double get_re() const{
            return re;
        }
        double get_im() const{
            return im;
        }

        complex comp_conj() const{
            complex temp;
            temp.set_re(re);
            temp.set_im(-im);
            return temp;
        }

        complex operator   (const complex amp;c)const{
            complex temp(re   c.get_re(), im   c.get_im());
            return temp;
        }

        complex operator - (const complex amp;c)const{
            complex temp(re - c.get_re(), im - c.get_im());
            return temp;
        }

        complex operator * (const complex amp;c1)const{
            complex temp;
            double a(re), b(im), c(c1.get_re()), d(c1.get_im());
            temp.set_re(a*c - b*d);
            temp.set_im(b*c   a*d);
            return temp;
        }

        complex operator / (const complex amp;c1)const{
            complex temp;
            double a(re), b(im), c(c1.get_re()), d(c1.get_im());
            temp.set_re((a*c   b*d)/(pow(c,2)   pow(d,2)));
            temp.set_im((b*d - a*d)/(pow(c,2)   pow(d,2)));
            return temp;
        }

        double mod() const{
            return(sqrt(pow(re,2)   pow(im,2)));
        }

        double arg() const{
            return(atan(im/re));
        }

        friend ostream amp; operator << (ostream amp;mm, const complex amp;c);
    };
ostream amp; comp::operator<< (ostream amp;mm, const complex amp;c){
    if(c.get_im() >= 0){
        mm << "(" << c.get_re() << "   " << c.get_im() << "i)" << endl;
    }
    if(c.get_im() < 0){
        mm << "(" << c.get_re() << " - " << -(c.get_im()) << "i)" << endl;
    }
    return mm;
}
}
#endif
  

Файл заголовка 2:

 #ifndef AC_Circuits_Header
#define AC_Circuits_Header
#include "Complex and Definitions.h"
#include<fstream>
#include<vector>
#include<string>

using namespace std;
using namespace comp;

class component{
public:
    virtual ~component(){}
    virtual void set_f(double m){}
    virtual double get_f() = 0;

    virtual complex impedance() = 0;
    virtual double reactance() = 0;
    virtual double phase_diff() = 0;
};

class resistor : public component{
protected:
    double R;
    bool para_or_series;
public:
    resistor(){R = para_or_series = 0;}
    resistor(double r_in, bool a){
        R = r_in;
        para_or_series = a;
    }
    ~resistor(){}

    double get_R(){return R;}
    void set_f(double m){}
    double get_f(){return 0;}

    complex impedance(){
        complex Z_R(R, 0);
        return Z_R;
    }

    double reactance(){return 0;}
    double phase_diff(){return 0;}
};

class capacitor : public component{
protected:
    double C, f;
    bool para_or_serie;
public:
    capacitor(){C = para_or_serie = 0;}
    capacitor(double c_in, bool a){
        C = c_in;
        para_or_serie = a;
    }
    ~capacitor(){}

    double get_C(){return C;}
    void set_f(double freq){f = freq;}
    double get_f(){return f;}

    complex impedance(){
        complex Z_C(0, (pow((2 * 3.14 * f * C), -1)));
        return Z_C;
    }

    double reactance(){
        return (-(pow((2 * 3.14 * f * C), -1)));
    }

    double phase_diff(){
        complex Z_C(0, (pow((2 * 3.14 * f * C), -1)));
        return Z_C.arg();   
    }
};

class inductor : public component{
protected:
    double L, f;
    bool para_or_series;
public:
    inductor() : L(0), para_or_series(0) {}
    inductor(double l_in, bool a) : L(l_in), para_or_series(a) {}
    ~inductor(){}

    double get_R(){return 0;}
    double get_C(){return 0;}
    void set_f(double b){f = b;}
    double get_f(){return f;}

    double reactance(){
        return (2 * 3.14 * f * L);  
    }

    complex impedance(){
        complex Z_L(0, (2 * 3.14 * f * L));
        return Z_L;
    }

    double phase_diff(){
        complex Z_L(0, (2 * 3.14 * f * L));
        return Z_L.arg();
    }
};

class circuit : public resistor, public capacitor, public inductor{
protected:
    complex Z_tot;
public:
    circuit() : Z_tot(0,0) {}
    circuit(bool a, resistor amp;R, capacitor amp;C, inductor amp;L){
        if(a == 1){
            Z_tot = R.impedance()   C.impedance()   L.impedance();
        }
        if(a == 0){
            complex one(1,0);
            Z_tot = one/(one/R.impedance()   one/C.impedance()   one/L.impedance());
        }
    }
    ~circuit(){}

    void set_f(){}
    double get_f(){return 0;}

    complex impedance(){}
    double reactance(){return 0;}
    double phase_diff(){return 0;}
};
#endif
  

cpp-файл один:

 #include "AC Circuits.h"

using namespace comp;

vector<component *> cmp;

void add_resistor(){
    double res;
    string p_or_s;
    bool a, b(1);

    cout << "You have chosen to add a resistor.nPlease input the resistance in ohms.n (If you do not want to add a resistor input 0)n"; // add in 0 functionality
    cin >> res;
    while(b){
        cout << "Is the resistor connected in series or in parallel?n";
        cin >> p_or_s;
        if(p_or_s == "Parallel" || p_or_s == "parallel" || p_or_s == "P" || p_or_s == "p"){
            a = 1;
            b = 0;
        }
        if(p_or_s == "Series" || p_or_s == "series" || p_or_s == "S" || p_or_s == "s"){
            a = 0;
            b = 0;
        }
        else{
            cerr << "ERROR: Your selection is invlaid, please input whether the resistor is connected in series or in parallel.n";
        }
    }

    cmp.push_back(new resistor(res, a));
}

void add_capacitor(){
    double cap;
    string p_or_s;
    bool a, b(1);

    cout << "You have chosen to add a capacitor.nPlease input the capacitance in ohms.n (If you do not want to add a capacitor input 0)n";
    cin >> cap;
    while(b){
        cout << "Is the capacitor connected in series or in parallel?n";
        cin >> p_or_s;
        if(p_or_s == "Parallel" || p_or_s == "parallel" || p_or_s == "P" || p_or_s == "p"){
            a = 1;
            b = 0;
        }
        if(p_or_s == "Series" || p_or_s == "series" || p_or_s == "S" || p_or_s == "s"){
            a = 0;
            b = 0;
        }
        else{
            cerr << "ERROR: Your selection is invlaid, please input whether the capactior is connected in series or in parallel.n";
        }
    }
    cmp.push_back(new capacitor(cap, a));
}

void add_inductor(){
    double ind;
    string p_or_s;
    bool a, b(1);

    cout << "You have chosen to add an inductor.nPlease input the inductance in henries.n (If you do not want to add an inductor input 0)n";
    cin >> ind;
    while (b){
        cout << "Is the inductor connected in series or in parallel?n";
        cin >> p_or_s;
        if(p_or_s == "Parallel" || p_or_s == "parallel" || p_or_s == "P" || p_or_s == "p"){
            a = 1;
            b = 0;
        }
        if(p_or_s == "Series" || p_or_s == "series" || p_or_s == "S" || p_or_s == "s"){
            a = 0;
            b = 0;
        }
        else{
            cerr << "ERROR: Your selection is invlaid, please input whether the resistor is connected in series or in parallel.n";
        }
    }
    cmp.push_back(new inductor(ind, a));
}
  

cpp-файл два:

 #include "AC Circuits.h"

int main(){
    return 0;
}
  

Когда я перемещаю main в конец первого cpp-файла, проблем нет, тогда как когда он находится в отдельном cpp-файле, появляются LNK1169 и LNK2005, но я бы предпочел, чтобы main был отдельным cpp-файлом.

Если до этого дойдет, я просто добавлю это в конец первого cpp, но, надеюсь, до этого не дойдет.

Комментарии:

1. Опубликуйте ошибки точно так, как они отображаются в IDE Visual Studio. То есть весь список сообщений об ошибках.

2. Убедитесь, что вы активировали кнопку «{}» после выделения вашего кода. Таким образом, < и > не исчезнут.

3. @Chai Пожалуйста, будьте осторожны при публикации вашего кода, чтобы правильно его отформатировать . И особенно при публикации такого огромного фрагмента, как этот!

4. Ваш main действительно ничего не делает?

5. Если вы еще этого не сделали, возможно, вам захочется взглянуть на: cubicspot.blogspot.com/2007/06 /…

Ответ №1:

Переместите определение

 std::ostream amp; operator<< (ostream amp;mm, const comp::complex amp;c)
  

в одном из CPP-файлов.

Компоновщику это не нравится. Лично я бы тоже создал новый cpp-файл для этого 🙂

Комментарии:

1. Фантастика! Большое вам спасибо за вашу помощь, причем так быстро. Я должен был это заметить, но это старый заголовок, который я создал и не стал рассматривать его слишком подробно. Прошу прощения за ужасное форматирование моего кода, я (очевидно) новичок на этом сайте: P Если это не слишком много, возможно, вы могли бы помочь мне с последней проблемой: в новом основном cpp-файле я, кажется, не могу вызвать функции, определенные в другом cpp-файле. Опять же, я чувствую, что это проблема «школьника», но эй; Я довольно новичок в программировании, и каждый должен с чего-то начинать, верно? Заранее благодарю вас за вашу помощь.

2. Вычеркните это, это была ошибка школьника, лол. Мне просто нужно было создать прототип функций. Большое вам спасибо за вашу помощь

Ответ №2:

Когда вы определяете автономную функцию (с телом) в заголовочном файле, вы должны использовать встроенную (функции, определенные в определении класса, по умолчанию являются встроенными).

Например, в заголовочном файле должно быть :

 inline ostreamamp; operator<< (ostream amp;mm, const complex amp;c){
    if(c.get_im() >= 0){
        mm << "(" << c.get_re() << "   " << c.get_im() << "i)" << endl;
    }
    if(c.get_im() < 0){
        mm << "(" << c.get_re() << " - " << -(c.get_im()) << "i)" << endl;
    }
    return mm;
}
  

В противном случае вы будете определять эту функцию в каждой единице перевода, которая включает этот заголовок, и, следовательно, можете получить ошибку множественного определения.

Ответ №3:

Пример для воспроизведения LNK1169 amp; LNK2005 с помощью структур: Поместите следующее в файл заголовка:

     Struct Foo
    {
    std::wstring Bar[3]
    };

    Foo InitFoo[2]
    {
    {L"ConstBar1Val", L"ConstBar1Val2", L"ConstBar1Val3"},
    {L"ConstBar2Val", L"ConstBar2Val2", L"ConstBar3Val3"}
    };
  

Решение: Переместите инициализированную структуру и массивы в соответствующий cpp-файл.

Комментарии:

1. Похоже, это не имеет большого отношения к вопросу (на который, кстати, был дан ответ семь лет назад )

2. @Легкие гонки на орбите: Нет, это не так. Только ошибки. Может быть, вместо этого отдельный вопрос-ответ?