C++ 未解析的外部符号、头文件原因

C++ 未解析的外部符号、头文件原因,c++,linker,unresolved-external,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, cons

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

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);
};
#包括
类理性{
公众:
有理(inta=0,intb=1);
有理数(constrational和number);
~Rational();
静态Rational添加(constrational&a、constrational&b);
静态Rational sub(常量Rational&a、常量Rational&b);
静态Rational mult(constrational&a、constrational&b);
静态Rational div(constrational&a、constrational&b);
空洞缩小(理性a);
int get_nom()常量;
int get_denom()常量;
无效集合名称(INTA);
无效集合(int b);
无效打印输出();
私人:
国际名称;
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);
    }
};
#include <iostream>
#include <Rational.h>

int main(){
Rational a(5,3);
a.printOut();
}
#包括
类理性{
公众:
有理(inta=0,intb=1):
名称(a)、名称(b){
}
有理数(常量有理数和数字):
nom(number.get_nom()),denom(number.get_denom()){
}
~Rational(){
}
静态Rational添加(constrational&a、constrational&b){
有理和((a.get_nom()*b.get_denom())+(a.get_denom()*b.get_denom()),(a.get_denom()*b.get_denom());
sum.reduce();
回报金额;
}
静态Rational sub(常量Rational&a、常量Rational&b){
有理微分(((a.get_nom()*b.get_denom())-(a.get_denom()*b.get_denom()),(a.get_denom()*b.get_denom());
diff.reduce();
返回差;
}
静态Rational mult(constrational&a、constrational&b){
有理乘积(a.get_nom()*b.get_nom(),a.get_denom()*b.get_denom());
乘积.reduce();
退货产品;
}
静态Rational div(constrational&a、constrational&b){
有理商(a.get_nom()*b.get_denom(),a.get_denom()*b.get_nom());
商reduce();
返回商;
}
void reduce(){
int-ggT=greatCommonDiv(nom,denom);
nom=nom/ggT;
denom=denom/ggT;
}
int get_nom()常量{return nom;}
int get_denom()常量{return denom;}
空集_nom(int a){nom=a;}
无效集_denom(int b){denom=b;}
无效打印输出(){

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

编译器是正确的。您可以/应该/必须只定义一次类,就像您在头文件中正确定义的那样。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::
作为前缀。
您在标题中定义的内容(如构造函数)无需再次定义。

因此您自己解决了链接器问题。关于“类类型重新定义”:

编译器是正确的。您可以/应该/必须只定义一次类,就像您在头文件中正确定义的那样。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::
作为前缀。
你在头文件中定义的东西(比如你的构造函数)你不必再定义了。

你编译Rational.cpp得到Rational.obj了吗?你在尝试创建可执行文件时链接到Rational.obj了吗?可能是重复的我刚刚在Visual Studio中点击了F7,打算让它在控制台窗口中运行。我添加了“#include”Rational.h”对于.cpp文件,错误消失了,但我得到的是“Rational:”类“类型重新定义”。你不能在Rational.h和Rational.cpp中都有类声明-你的Rational.cpp的语法是完全不合适的。Rational.cpp应该只包含类的方法定义,而不是类定义-再买本书-这些都是非常基础的。你编译Rational.cpp来获得Rational.obj了吗?你在尝试创建可执行文件时链接了Rational.obj了吗?我刚刚在Visual Studio中点击了F7,希望它能在控制台窗口中运行。我添加了“#include”Rational.h”对于.cpp文件,错误消失了,但我得到的是“Rational:”类“类型重新定义”。你不能在Rational.h和Rational.cpp中都有类声明-你的Rational.cpp的语法是完全不合适的。Rational.cpp应该只包含类的方法定义,而不是类定义-再买本书-这些都是非常基本的。非常感谢。所以我在.cpp以及“类块”中取出了所有变量的初始化。但是我不应该在构造函数的前缀中加上“Rational::”,因为我在.cpp中定义它,与在.h文件中的声明不同吗?如果你在cpp中定义它:是的。但是有一个complete定义在您的头文件中,您可以将其保留在那里,而不要在cpp中提及它。很抱歉,我看不到构造函数和析构函数在.h文件中是一个完整的定义。我需要如何更改代码才能使其正确?此外,编译器现在告诉我“静态不应用于在add/sub/mult/div函数的文件作用域。哦,对不起,我看错了地方。你是对的:你还需要定义构造函数,就像方法一样。非常感谢。所以我在.cpp中取出了所有变量的初始化以及“类块”。但是我不应该在构造函数前面加上“Ration”前缀吗al::'也是因为我在.cpp中定义它,与在.h文件中的声明不同?如果你在cpp中定义它:是的。但是在头文件中有一个完整的定义,你可以把它放在那里,永远不要在cpp中提及它。对不起,我看不出构造函数和析构函数在.h文件中是如何完整定义的。你怎么知道呢我需要更改代码才能正确吗?另外,公司