未解析的外部符号,头文件原因

时间:2013-08-06 09:09:04

标签: c++ linker unresolved-external

我已经搜索(并找到)了这个错误的主题,但是还没能将它们应用到我的具体情况中。所以这就是:

Rational.h

#include <iostream>
class Rational{
public:
    Rational(int a = 0, int b = 1);
    Rational(const Rational &number);
    ~Rational();

    static Rational add(const Rational &a, const Rational &b);
    static Rational sub(const Rational &a, const Rational &b);
    static Rational mult(const Rational &a, const Rational &b);
    static Rational div(const Rational &a, const Rational &b);

    void reduce(Rational a);

    int get_nom() const;
    int get_denom() const;
    void set_nom(int a);
    void set_denom(int b);

    void printOut();

private:
    int nom;
    int denom;

    int greatCommonDiv(int a, int b);
};

Rational.cpp

#include <iostream>

class Rational{
public:
    Rational(int a = 0, int b = 1):
        nom(a), denom(b){
    }
    Rational(const Rational &number):
        nom(number.get_nom()), denom(number.get_denom()){
    }
    ~Rational(){
    }

    static Rational add(const Rational &a, const Rational &b){
        Rational sum( ((a.get_nom() * b.get_denom()) + (a.get_denom() * b.get_denom())), (a.get_denom() * b.get_denom()) );
        sum.reduce();
        return sum;
    }
    static Rational sub(const Rational &a, const Rational &b){
        Rational diff( ((a.get_nom() * b.get_denom()) - (a.get_denom() * b.get_denom())), (a.get_denom() * b.get_denom()) );
        diff.reduce();
        return diff;
    }
    static Rational mult(const Rational &a, const Rational &b){
        Rational product(a.get_nom() * b.get_nom(), a.get_denom() * b.get_denom());
        product.reduce();
        return product;
    }
    static Rational div(const Rational &a, const Rational &b){
        Rational quotient(a.get_nom() * b.get_denom(), a.get_denom() * b.get_nom());
        quotient.reduce();
        return quotient;
    }
    void reduce(){
        int ggT = greatCommonDiv(nom, denom);
        nom = nom / ggT;
        denom = denom / ggT;
    }

    int get_nom() const { return nom; }
    int get_denom() const { return denom; }
    void set_nom(int a){ nom = a; }
    void set_denom(int b){ denom = b; }

    void printOut(){
        std::cout << nom << "/" << denom << std::endl;
        return;
    }

private:
    int nom;
    int denom;

    int greatCommonDiv(int a, int b){           
        if(b == 0)
            return a;
        else return greatCommonDiv(b, a % b);
    }
};

Source.cpp

#include <iostream>
#include <Rational.h>

int main(){
Rational a(5,3);
a.printOut();
}

MSVS给了我3个错误:

  

1&gt; Source.obj:错误LNK2019:未解析的外部符号“public:__thiscall Rational :: Rational(int,int)”(?? 0Rational @@ QAE @ HH @ Z)在函数_main中引用

     

1&gt; Source.obj:错误LNK2019:函数_main

中引用的未解析的外部符号“public:__thiscall Rational :: ~Rational(void)”(?? 1Rational @@ QAE @ XZ)      

1&gt; Source.obj:错误LNK2019:未解析的外部符号“public:static void __cdecl Rational :: printOut(void)”(?printOut @ Rational @@ SAXXZ)在函数_main中引用

我无法弄清楚,为什么会发生这种情况,因为我非常肯定他可以在正确的位置找到.h和.cpp文件。

1 个答案:

答案 0 :(得分:1)

所以你自己解决了链接器问题。关于“类型重新定义”:

编译器是对的。你可以/必须/必须只定义一次类,就像你在头文件中正确做的那样。 cpp文件应该是这样的:

#include "Rational.h"

Rational Rational::add(const Rational &a, const Rational &b){
    Rational sum( ((a.get_nom() * b.get_denom()) + (a.get_denom() * b.get_denom())), (a.get_denom() * b.get_denom()) );
    sum.reduce();
    return sum;
}

...

你得到了基本的想法:无论在标题中没有定义(仅声明),你在cpp中定义。始终以Classname::为前缀。 您在标题中定义的内容(如构造函数),您不必再次定义。