在函数之前使用 inline 关键字和在头文件中声明整个函数有什么区别?
所以...
int whatever() { return 4; }
对比
。H:
inline int whatever();
.cpp:
inline int myClass::whatever()
{
return 4;
}
就此而言,这是做什么的:
inline int whatever() { return 4; }
在函数之前使用 inline 关键字和在头文件中声明整个函数有什么区别?
所以...
int whatever() { return 4; }
对比
。H:
inline int whatever();
.cpp:
inline int myClass::whatever()
{
return 4;
}
就此而言,这是做什么的:
inline int whatever() { return 4; }
有几个方面:
语
inline
关键字标记时,它的定义应该在 TU 中可用,否则程序格式错误。inline
。inline
(隐式或显式)的功能可以在多个 TU 中定义(尊重 ODR),而常规功能则不是这种情况。inline
的处理。编译器行为
inline
将在每个需要的目标文件中作为弱符号发出,这可能会增加它们的大小(查找模板膨胀)。链接器行为
的目的inline
是允许在多个翻译单元中定义一个函数,这对于某些编译器能够在任何使用它的地方内联它是必要的。每当您在头文件中定义函数时都应该使用它,尽管您可以在定义模板或类定义中的函数时省略它。
在没有标题的情况下定义它inline
是一个非常糟糕的主意。如果您包含来自多个翻译单元的标题,则您违反了一个定义规则;您的代码可能不会链接,并且如果链接可能会表现出未定义的行为。
在头文件中声明它inline
但在源文件中定义它也是一个非常糟糕的主意。该定义必须在任何使用它的翻译单元中可用,但通过在源文件中定义它只能在一个翻译单元中使用。如果另一个源文件包含头文件并尝试调用该函数,则您的程序无效。
没有, 如果函数是在命名空间或全局范围内声明的(导致链接器错误)inline
,您可能最终会得到多个导出的符号。
但是,对于一个类(如您的示例中所示),大多数编译器隐式将该方法声明为内联(-fno-default-inline
将在 GCC 上禁用该默认值)。
如果您将函数声明为内联,编译器可能希望在翻译中看到它的定义。因此,您应该在定义可见时保留它。
在更高级别:类声明中的定义通常对更多翻译可见。这可以带来更好的优化,并且可以增加编译时间。
除非手动优化和快速编译都很重要,否则现在在类声明中使用关键字是不寻常的。
这个问题解释了很多关于内联函数的内容__inline__ 是什么意思?(即使它是关于inline关键字。)
基本上,它与标题无关。在头文件中声明整个函数只会更改函数源所在的源文件。 inline 关键字修改生成的编译函数的放置位置 - 在它自己的位置,以便每个调用都会去那里或就地每次通话(更好的性能)。然而,编译器有时会选择为自己内联的函数或方法,而关键字只是对编译器的建议。即使没有指定内联的函数也可以由编译器选择为内联,如果这样可以提供更好的性能。
如果您将多个对象链接到一个可执行文件中,通常应该只有一个对象包含函数的定义。For int whatever() { return 4; }
- 任何用于生成对象的翻译单元都将包含whatever
函数的定义(即可执行代码)。链接器不知道将调用者定向到哪一个。如果inline
提供,则可执行代码可能会或可能不会在调用站点内联,但如果不是,则允许链接器假定所有定义都是相同的,并任意选择一个来引导调用者。如果不知何故定义不一样,那么它被认为是你的错,你会得到未定义的行为。使用inline
,在编译调用时必须知道定义,因此您将内联声明放在头文件中并将内联定义放在 .cpp 文件中的想法只有在所有调用者碰巧稍后在同一个 .cpp 文件中时才有效 - 在一般它已损坏,并且您希望(名义上)内联函数的定义出现在声明它的标头中(或者没有事先声明的单个定义)。