如果多个.cpp文件是#included会发生什么?

时间:2009-05-17 21:35:23

标签: c++ include

我已经看过(和使用过)这样的情况:

在header.h中:

class point
{
public:
    point(xpos, ypos);
    int x;
    int y;
};

在def.cpp中:

#include"header.h"
point::point(xpos, ypos)
{
    x = xpos;
    y = ypos;
}

在main.cpp中:

#include"header.h"
int main()
{
    point p1(5,6);
    return 0;
}

我知道程序是从main执行的,但是编译器如何知道编译.cpp文件的顺序是什么? (特别是如果有多个非主.cpp文件)。

7 个答案:

答案 0 :(得分:10)

编译器无关紧要 - 它将每个.cpp文件编译成.obj文件,而.obj文件每个都包含一个缺失符号列表。所以在这种情况下,main.obj说“我缺少point::point”。

然后链接器的工作是获取所有.obj文件,将它们组合成一个可执行文件,并确保每个.obj文件的缺失符号都可以从另一个文件中获得。 obj文件 - 因此称为“链接器”。

答案 1 :(得分:4)

如果将它们包含在两个不同的cpp文件中,那就没问题了。 如果两次包含相同的标题,则会出现重复定义的错误。

你应该使用包含警戒来规避这一点。

在您的文件之上,在任何代码之前:

#ifndef HEADER_H_ //every header gets it's own name
#define HEADER_H_

在底部:

#endif

答案 2 :(得分:1)

编译顺序无关紧要。所有内容都由编译器编译,编译器使用.h文件来确保至少声明您使用的符号。这是链接器的工作,它在编译器完成后执行,实际上将方法调用与它们的实现匹配。

答案 3 :(得分:1)

编译器不需要知道编译.cpp文件的顺序。

链接器将所有单独编译的.o(从.cpp构建)文件排序,并将所有内容解析为一个可执行文件。

答案 4 :(得分:0)

通常您自己单独编译它们(或使用像make这样的构建工具)。头文件允许您以任何顺序编译它们。如果你一起编译它们,顺序可能就是你传递给编译器命令的顺序,但它实际上并不重要,它们最终都被链接到一个可执行文件中。

答案 5 :(得分:0)

这是图论应用的一个例子。已编译的模块包含所有代码块的相对偏移量,以及链接器在构造可执行文件时发现依赖关系(图形)。

答案 6 :(得分:-1)

这就是为什么你会在某些头文件的顶部看到#ifndef HEADER_H和#define HEADER_H的原因。例如,每个头文件只包含一个described here的概念。