【问题标题】:C++ build process (Including)C++构建过程(含)
【发布时间】:2017-08-29 18:45:27
【问题描述】:

我目前正在从一本名为 Alex Allain - Jumping into c++ 的书中学习 C++,但我被困在第 21 章。它详细介绍了 C++ 构建过程,我明白了,除了两部分:

第一:

“头文件不应包含任何函数定义。如果我们在头文件中添加了函数定义,然后将该头文件包含到多个源文件中,则函数定义将在链接时出现两次。这会使链接器感到困惑。”

第二:

“永远不要直接包含 .cpp 文件。包含 .cpp 文件只会导致问题,因为编译器会将 .cpp 文件中的每个函数定义的副本编译到每个目标文件中,并且链接器会看到多个相同函数的定义。即使您非常小心地执行此操作,也会失去单独编译节省时间的好处。”

谁能解释一下?

【问题讨论】:

  • 我认为您应该阅读有关函数定义和声明之间的区别。很确定它可以解决您的问题。

标签: c++ build linker include


【解决方案1】:

C++ 程序由一个或多个translation units 创建。每个翻译单元(简称 TU)基本上都是一个包含所有头文件的源文件。当你创建一个目标文件时,你实际上是在创建一个 TU。链接时,您将获取编译器创建的目标文件 (TU) 并将它们与库链接以创建可执行程序。

一个程序只能有一个定义。如果您有多个定义,则链接时会出错。定义可以是变量定义,例如

int a;

double b = 6.0;

也可以是函数定义,就是函数的实际实现。

您只能有一个定义的原因是因为这些定义在程序加载执行时被映射到内存地址。一个变量或一个函数不能同时存在于两个地方。

这是您不应将源文件包含到其他源文件中的原因之一。这也是你不应该在头文件中定义的原因,因为头文件可以包含在多个源文件中,因为这会导致定义在多个 TU 中。


当然也有例外,例如将函数标记为inlinestatic。但这已经解决了,因为这些定义不是从 TU 导出的,链接器看不到它们。

【讨论】:

    猜你喜欢
    • 2012-07-18
    • 1970-01-01
    • 2011-03-21
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    相关资源
    最近更新 更多