如果没有为类类型(struct,class或union)提供任何类型的用户声明构造函数,编译器将始终将默认构造函数声明为内联公共成员类。
为什么做出这个决定(明确地声明 ctors / dtors为内联)?无论如何编译器可以自由内联/非内联?特别是因为内联ctors可能会对一个类的客户造成巨大的惩罚(Effective C ++,Item#30)?
答案 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。标准中的措辞比我上面使用的内容更难理解,不同且更精确。