7

我只是对这个问题感到好奇,但在互联网上找不到答案。

假设我们有简单的标题:

// SimpleHeader.h
class SimpleClass
  {
  int i;
  }

我们知道,这个类的默认构造函数是自动生成的。

现在我还有 2 个文件:

// First.cpp
#include <SimpleHeader.h>
// ...
SimpleClass a;
// ...

//Second.cpp
#include <SimpleHeader.h>
// ...
SimpleClass b;
// ...

First.obj 和 Second.obj 是否都包含该类的代码

4

5 回答 5

4

从标准看:如果你不写任何构造函数,会为你提供一个默认构造函数,并且这个默认构造函数是内联定义的,相当于一个空的构造函数T::T() {}

我很确定[编辑]你这样内联的构造函数实际上根本不会产生任何机器代码。

于 2011-09-08T14:27:01.483 回答
3

是的,大概编译器必须在两个目标文件中生成代码,以防它们最终没有链接在一起。然后,当您将两个目标文件链接到可执行二进制文件中时,链接器使用一个定义规则来选择一个版本并丢弃另一个版本。

于 2011-09-08T14:26:58.607 回答
3

首先,它肯定取决于编译器,以及许多其他情况。

这里有 3 个常见的场景。

  1. 默认构造函数会生成并包含在您的每个 First.obj 和 Second.obj 对象文件中,但是当您将它们链接在一起以生成可执行文件时,仅使用并包含其中一个。

  2. 构造函数在您创建对象的任何地方都内联(通常仅用于简单的构造函数,编译器可以将内存归零的地方)

  3. 无需生成/调用默认构造函数。如果您在文件范围内声明一个对象并且该对象只需要将其内存初始化为零,则可能会发生这种情况 - 编译器可能只是将对象放置在程序启动时初始化为零的特殊区域中 - 并忽略完全调用默认构造函数。

于 2011-09-08T14:38:19.603 回答
0

默认构造函数不过是为对象分配空间。因为它不是动态变量,所以在加载器阶段已经分配了内存,不需要更多代码。

更有趣的是,如果您实现了一个复杂的构造函数并动态分配对象会发生什么。
在这种情况下,两个 obj 文件都将具有构造函数代码。

于 2011-09-08T14:04:05.967 回答
0

两者都不。在 C 和 C++ 中,你可以多次声明一些东西,比如,有这个函数的代码,但它在别的地方。您只能定义一次,并且在您定义它的地方,即在该 obj 文件中生成代码的地方。所以,你有三个 .cpp 文件和一个头文件,第一个文件定义了类,另外两个是它的对象。其他两个文件的 obj 文件将不包含该类的任何代码,只有一些足以让链接器调用代码的信息是定义文件的 obj。

如果您在两个地方定义类,通过将方法定义隐式放在包含在多个文件中的标头中,链接器不会介意,因为定义是“相同的”,它们只是碰巧最初出现在每个 obj 中,并且最终应用程序将仅包含生成的一个默认函数之一。

您可以随时创建任意数量的类实例,并且永远不会复制方法代码。对于所有不同的文件、函数等,它存在于一个位置,以便使用和制作该类的对象。

一些默认构造函数可能很聪明并且需要一些代码,例如一些用于 POD 结构的可能完全优化并且不需要任何代码。尽管创建更多实例并不会复制任何函数,包括构造函数,但情况总是如此。

于 2011-09-08T14:27:34.820 回答