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

19

我从多个来源上读到:

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

为什么要做出这个决定(明确地声明构造函数/析构函数为内联函数)?编译器不管是否内联都是自由的决定吗?特别是因为内联构造函数可能会对类的客户端产生巨大的惩罚(《Effective C++》中的Item #30)?


18
现在,inline声明与编译器的内联几乎没有任何关系。这主要是一种奇怪的拼写方式,表示“允许有多个定义”。 - molbdnilo
6
为了允许在多个翻译单元中进行(隐式)定义,一如既往。 - cpplearner
2个回答

32
他们不是以“编译器将始终内联它们”的意义内联。他们以“在每个看到类定义的翻译单位中都被认为已定义,而不违反一次定义规则(ODR)”的意义内联。请注意,后者是标准C++使用“内联函数”这个短语的唯一含义。

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


11
建议添加一个缩写词ODR的链接,如ODR - chux - Reinstate Monica
3
我记得有关于inline的另一种用法的非规范性文本,是我记错了吗? - Yakk - Adam Nevraumont
2
所以,angew,这个答案不正确;在C++标准中,“inline”这个词还有另一种含义。 - Yakk - Adam Nevraumont
但这个变量并不需要被编译器所认可。 - cHao
1
@Yakk 哎呀,实际上这甚至是规范的。感谢您指出,答案已更新。 - Angew is no longer proud of SO
换句话说,inline 是一个链接器关键字。 - v.oddou

30

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

第一个含义是当你听到 inline 时想到的那种;将函数中的代码注入到调用它的地方。

C++ 标准建议实现在看到 inline 方法或函数时这样做,但不要求这样做。由于这种行为对 C++ 标准描述的抽象机器没有任何可观察到的行为变化,我认为这是非规范性建议。

第二个含义与链接有关。一个 inline 函数(或在 C++17 中的变量)可以存在于多个翻译单元中。通常情况下,在链接时间会出现错误;但是当变量或函数是 inline 时,除了其中一个实例外,所有其他实例都会被静默丢弃。如果它们在任何重要方面不同,这将导致程序 ill-formed,但不需要诊断。

这第二个意义是隐式构造函数和析构函数被隐式定义为内联的原因;这意味着不需要选择一个单一的翻译单元来存放它们。相反,它们会在需要时随处生成。它们可能会被优先实际内联到调用代码中,但最重要的是,如果它仍然存在一些残留副本(例如没有内联),则在链接时间不会出现错误,而是丢弃所有除一个之外的副本。

请参见 C++ 标准中的 inline。标准中的措辞比我上面使用的措辞更加难以理解,但更为精确不同。


2
感谢您实际上完整地回答了这个问题。+1 - user541686
更多信息请访问:https://akrzemi1.wordpress.com/2014/07/14/inline-functions/ - j4nu5
Effective C++,条款#30 以默认构造函数为例,不建议将其声明为内联。因此,由于构造函数默认为内联,因此该示例不存在? - daohu527

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接