【问题标题】:What happens if more than one .cpp file is #included?如果#included 有多个.cpp 文件会怎样?
【发布时间】:2009-05-17 21:35:23
【问题描述】:

因为我见过(并使用过)这样的情况:

在 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 文件)。

【问题讨论】:

    标签: c++ include


    【解决方案1】:

    编译器 不在乎 - 它会将每个 .cpp 文件编译成 .obj 文件,每个 .obj 文件都包含一个缺失符号列表。所以在这种情况下,main.obj 会说“我错过了point::point”。

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

    【讨论】:

    • 通常是 .o 文件,而不是 .obj(但实际上并不重要)。
    • 它们不是“通常”的东西。 GCC 默认生成 .o 文件,Visual Studio 生成 .obj。两者都不比另一个更“平常”。
    【解决方案2】:

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

    您应该使用包含保护来规避这一点。

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

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

    在底部:

    #endif
    

    【讨论】:

    • 我投票赞成 b/c 这是一个重要的模式,有助于这个讨论并为 IMO 增加了很多价值。
    • 否:OP 询问的是几个 CPP 文件的编译顺序(正确的答案是它们的编译顺序无关紧要,因为它们是独立编译的) ; OP 没有询问每个 CPP 文件中包含头文件的顺序。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-06-08
              • 2011-04-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多