1

我已经知道,当我将成员函数的定义放入标头并将函数标记为 时,函数中inline的代码会内联到从 .cpp 文件中调用函数的任何位置,所以当涉及到一个已编译的二进制文件,我知道函数代码的位置——在任何依赖它的 .cpp 文件的编译代码中。但是如果我不在标头中标记函数会发生什么inline并且函数体大到足以让编译器选择不内联它?在函数的类所属的静态/动态库的上下文中,函数的代码编译到哪里?或者它根本没有编译,函数代码的最终目的地是库客户端的已编译 .cpp?如果是后一种情况,即使我没有用它标记函数的代码是否仍然被内联inline(因为它的代码太“重”)?最后,MSVC 编译器在这种情况下的行为是否与 GCC 不同?

当然,我意识到将要内联的成员函数放入 .h 文件(或 .inl 文件)并将“重”函数放入 .cpp 文件会使事情变得一目了然,但我真的很想避免破坏一个类'跨文件实现,因此很有趣。

4

3 回答 3

4

它直接编译到包含您的标题的每个翻译单元中。如果有多个这样的文件,则您违反了一个定义规则并使您的程序格式错误。

如果您真的想将所有代码放在一个文件中,请将其放在标题中并将函数标记为内联。这只是一个建议,所以如果函数太大,编译器无论如何都不会内联它,它会像非内联函数一样编译。但请注意,这不是规范的 C++,因为它会大大增加编译时间。正常模式实际上是将接口(标头)与实现(源文件)分开。如果编译器决定不内联函数,它将被写入每个包含头文件的翻译单元的编译目标文件中,并且链接器将需要从其中一个目标文件中选择一个实例,丢弃其余的(因为每个版本的代码都是相同的)。

于 2012-07-06T19:01:54.960 回答
4

当你标记一个函数inline时,你并没有强制编译器在它被调用的每个地方都内联它,你只是告诉它定义是内联的,它应该期望在不同的编译单元中有重复的副​​本。对于包含标头并调用函数的每个编译单元,实际代码将至少编译一次。

如果您不将其声明为内联,则链接器应该抱怨函数的多个定义,即使这些定义是相同的。

于 2012-07-06T19:08:29.360 回答
2

如您所知,“内联”只是对编译器的“请求”——仅此而已。

此外,没有什么可以阻止您在标头中声明独立的“静态”函数。此时,相同的二进制代码在其源文件#include 为标头的每个目标文件中都会被重复。

你猜怎么着——内联函数也会发生同样的事情:)

就个人而言,我喜欢在头文件中只看到和结构定义、typedef、常量、函数原型……和 externs……。

于 2012-07-06T19:06:03.637 回答