为什么类的默认构造函数和析构函数是内联的?

时间:2017-12-21 14:03:34

标签: c++

我从multiple sources读到:

  

如果没有为类类型(struct,class或union)提供任何类型的用户声明构造函数,编译器将始终将默认构造函数声明为内联公共成员类。

为什么做出这个决定(明确地声明 ctors / dtors为内联)?无论如何编译器可以自由内联/非内联?特别是因为内联ctors可能会对一个类的客户造成巨大的惩罚(Effective C ++,Item#30)?

2 个答案:

答案 0 :(得分:31)

它们在某种意义上并不是内联的“它们将始终由编译器内联。”它们在某种意义上是内联的“在每个翻译单元中都被认为是定义了类定义,而不是违反One Definition Rule (ODR)。”请注意,后者是标准C ++使用的短语“内联函数”的唯一含义。

使用inline关键字明确标记函数也是编译器实际内联函数的非约束性提示,但我怀疑现代编译器和&优化者非常关注这个提示。但请注意,这(内联提示)仅适用于使用关键字inline,而不适用于隐式内联函数(例如问题中提到的默认构造函数和析构函数)。

答案 1 :(得分:28)

inline在C ++标准中有两个含义。

当你听到inline时,首先是你的想法;获取函数中的代码并将其注入调用函数的位置。

C ++标准建议实现在看到inline方法或函数时执行此操作,但不需要它。由于此类操作在C ++标准描述的抽象机器中没有可观察到的行为更改,因此我将其视为非规范性建议。

第二个与链接有关。 inline函数(或C ++ 17变量)可以存在于多个翻译单元中。通常这会在链接时导致错误;但是当变量或函数是inline时,变量或函数的所有实例都会被静默丢弃。如果它们在任何重要方面有所不同,这会使您的程序格式不正确,无需诊断。

这第二个含义是为什么隐含的ctors和dtors隐含内联;这意味着不必选择单个翻译单元来“生活”。相反,它们会在需要的任何地方生成。它们可能优先实际内联到调用代码中,但最重要的是,如果它的任何残留副本仍然存在(因为它没有内联,比方说),链接时不会发生错误,而是丢弃其中的一个。

请参阅C ++标准中的inline。标准中的措辞比我上面使用的内容更难理解,不同且更精确。