【问题标题】:Unresolved External Symbol, Header File Cause未解决的外部符号,头文件原因
【发布时间】:2013-08-07 05:03:54
【问题描述】:

我已搜索(并找到)此错误的主题,但无法将它们应用于我的具体情况。就这样吧:

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>Source.obj : 错误 LNK2019: 函数 _main 中引用的未解析的外部符号“public: __thiscall Rational::Rational(int,int)” (??0Rational@@QAE@HH@Z)

1>Source.obj : 错误 LNK2019: 函数 _main 中引用的未解析外部符号“public: __thiscall Rational::~Rational(void)”(??1Rational@@QAE@XZ)

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

我不知道为什么会发生这种情况,因为我很确定他可以在正确的位置找到 .h 和 .cpp 文件。

【问题讨论】:

  • 您是否编译了 Rational.cpp 以获得 Rational.obj?您在尝试创建可执行文件时是否在 Rational.obj 中进行了链接?
  • 我刚刚在 Visual Studio 中按 F7 并打算让它在控制台窗口中运行。我在 .cpp 文件中添加了 '#include "Rational.h",错误消失了,但我得到的是 'Rational: 'class' type redefinition'。
  • 你不能在 Rational.h 和 Rational.cpp 中都有类声明——你的 Rational.cpp 的语法是完全不合适的。 Rational.cpp 应该只包含类的方法定义,而不是再次包含类定义——买一本书——这些都是基础。

标签: c++ linker unresolved-external


【解决方案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.xml 中定义。始终以 Classname:: 为前缀。 你在标题中定义的东西(比如你的构造函数)你不必再次定义。

【讨论】:

  • 非常感谢。因此,我取出了 .cpp 以及“类块”中变量的全部初始化。但是我不应该让构造函数也以'Rational::'为前缀,因为我在.cpp中定义它与.h文件中的声明不同吗?
  • 如果你在cpp中定义它:是的。但是你的头文件中有一个完整的定义,你可以把它放在那里,不要在cpp中提及它。
  • 对不起,我没有看到构造函数和析构函数是如何在.h文件中完整定义的。我需要如何更改代码才能使其正确?
  • 此外,编译器现在告诉我,对于 add/sub/mult/div 函数,“静态不应用于在文件范围内定义的成员函数”。
  • 哦抱歉,我看错地方了。你是对的:你还需要定义构造函数,就像方法一样。
猜你喜欢
  • 2013-05-07
  • 2015-01-16
  • 2011-09-03
  • 2011-12-19
  • 2010-11-20
  • 1970-01-01
  • 2013-06-11
  • 2011-10-21
  • 2012-10-21
相关资源
最近更新 更多