文件包含错误(C++):未定义的引用______

问题描述:

每当我编的东西,来#include一个用户定义的类,我得到这些编译错误总是看起来像:main.cpp: undefined reference to Complex::Complex(double, double)文件包含错误(C++):未定义的引用______

我已经减少了问题的一组三个非常空的文件:main.cpp,例如Complex.h和Complex.cpp。我仍然收到未定义的参考错误。我在Windows上的Code :: Blocks中开发,但在Ubuntu中使用g ++获得了同样的结果。为什么会发生?我已经尝试过在Code :: Blocks中的main.cpp之前构建Complex.cpp,并且我尝试了g++ main.cpp Complex.cpp,就像我试过g++ main.cpp一样。每次都有相同的错误。

/*======== main.cpp ========*/ 
#include "Complex.h" 

int main() 
{ 
    Complex A(1.0, 1.0); 
    return 0; 
} 

/*======== Complex.h ========*/ 
#ifndef _COMPLEX_H 
#define _COMPLEX_H 

class Complex 
{ 
    public: 
    double x, y; 
    Complex(double real, double imag); 
}; 

#endif 

/*======== Complex.cpp ========*/ 
#include "Complex.h" 

Complex::Complex(double real, double imag) 
{ 
    x = real; 
    y = imag; 
} 

ed:现在我得到了不同的错误,所以我必须做一些完全错误的事情。使用与上面相同的代码,我得到:

main.cpp: in function 'int main()': 
main.cpp:5:5: error: 'Complex' was not declared in this scope 
main.cpp:5:13: error: expected ';' before 'A' 

这是离奇的。当我有一个.cpp文件中的类时,所有东西都工作得更早,但这是“不好的做法”,所以我将我的类定义移动到.h文件中,并将实现保存在.cpp文件中,现在什么都不起作用。

+1

另外一定要在编译行中加上“-I”。如果你的.h文件在同一个目录下,甚至可能是“-I”。 – paulsm4 2012-01-05 00:00:53

+3

它适合我。我只复制了你的'main.cpp','Complex.h'和'Complex.cpp',并运行'g ++ main.cpp Complex.cpp'。它创建'a.out'就好了。 – ruakh 2012-01-05 00:01:43

+1

也适用于我。 @ paulsm4:不应该''在默认包含路径中? (请注意,他正在执行'#include“...”',而不是'#include <...>') – 2012-01-05 00:03:23

这不是一个编译错误,它是一个链接错误。您需要确保将所有对象链接在一起。你可以用几种方法做到这一点:

g++ main.cpp Complex.cpp 

应该工作正常(并在这里,当我试着用你的例子)。你也可以做到这一点的步骤:

g++ -c main.cpp 
g++ -c Complex.cpp 
g++ main.o Complex.o 
+0

在这个问题中,它已经说过“我已经尝试过'g ++ main.cpp Complex.cpp” – 2012-01-05 00:12:17

+0

@AaronMcDaid,但他显然没有,因为那样会起作用。我想他也可以简化他的例子,但是这也不会帮助他得到正确的答案。 – 2012-01-05 00:12:56

+0

我同意。我已经提出了你的答案,因为它似乎显然是正确的:-)我想我们正在等待确切的错误消息的细节。 – 2012-01-05 00:16:18

虽然我们都留在了黑暗中,这是否是实际的代码(很可能不是因为它适用于其他几个人),让代码本身一点的评论... (这不会对链接器错误产生任何影响)

  1. 以下划线开头,后跟大写字母的名称,例如_COMPLEX_H保留用于实现C++编译器和C++标准库。 请勿使用
  2. 成员变量最好是private。很少有任何需要让实际的数据成员public(有时候做非功能成员public是合理的,例如用户可以预订回调的事件类,但是它们通常表现为功能,尽管它们在技术上是对象)。
  3. 初始化最好在成员初始值设定项列表中完成。也就是说,构造函数会是这个样子:

    复杂::复合物(双实数,双图像): X(真实), Y(IMAG) {}

最后,冒险几个猜测什么是错误的实际代码导致链接问题:

  1. 构造函数定义为inline。显然,除非定义在使用构造函数的地方可见,否则这将不起作用。
  2. Complex声明以某种方式将它变成了一个未命名的名称空间,因此定义恰好定义了与main.cpp所看到的类不同的类。