为什么头文件中的C ++内联函数?
注意这不是一个关于如何使用内联函数或它们如何工作的问题,更不是为什么它们按照它们的方式完成。
类成员函数的声明不需要将函数定义为inline
函数,它只是函数的实际实现。 例如,在头文件中:
struct foo{
void bar(); // no need to define this as inline
}
那么为什么类函数的内联实现必须位于头文件中呢? 为什么我不能把内联函数放在.cpp
文件中? 如果我在哪里尝试将内联定义放入.cpp
文件中,我会收到以下错误信息:
error LNK2019: unresolved external symbol
"public: void __thiscall foo::bar(void)"
(?bar@foo@@QAEXXZ) referenced in function _main
1>C:UsersMeDocumentsVisual Studio 2012ProjectsinlineDebuginline.exe
: fatal error LNK1120: 1 unresolved externals
inline
函数的定义不必位于头文件中,但由于内联函数的一个定义规则,函数的相同定义必须存在于每个使用它的翻译单元中。
最简单的方法是将定义放在头文件中。
如果你想把一个函数的定义放在一个源文件中,那么你不应该声明它是inline
。 函数没有声明inline
并不意味着编译器不能内联函数。
无论你是否应该声明一个inline
函数,通常都是你应该根据哪个版本的定义规则进行选择,它对你来说最有意义; 添加inline
然后受后续约束限制是没有意义的。
有两种方法可以查看它:
内联函数在头文件中声明,因为为了内联函数调用,编译器必须能够看到函数体。 对于一个天真的编译器来说,函数体必须与调用位于同一个翻译单元中。 (现代编译器可以跨翻译单元优化,因此即使函数定义位于单独的翻译单元中,也可以内联函数调用,但这些优化非常昂贵,并不总是启用,并且并不总是受编译)
函数中声明的函数必须标记为inline
,否则包含头的每个翻译单元都将包含该函数的定义,并且链接器将会抱怨多个定义(违反One Definition Rule)。 inline
关键字取消了这一点,允许多个翻译单元包含(相同的)定义。
这两个解释实际上归结为inline
关键字并不完全符合您的期望。
只要它不改变程序的可观察行为,C ++编译器就可以随意应用内联优化(将被调用函数的主体替换为函数调用,从而节省调用开销)。
inline
关键字使编译器更易于应用此优化,允许函数定义在多个翻译单元中可见,但使用关键字并不意味着编译器必须内联该函数,并且不使用关键字doesn' t禁止编译器内联函数。
这是C ++编译器的限制。 如果将函数放在标题中,所有可以内联的cpp文件都可以看到函数的“源”,并且内联可以由编译器完成。 另外,内联必须由链接器完成(每个cpp文件分别在obj文件中编译)。 问题是在链接器中执行它会困难得多。 “模板”类/函数存在类似的问题。 它们需要由编译器实例化,因为链接器会出现问题实例化(创建专用版本)。 一些较新的编译器/链接器可以进行“两遍”编译/链接,编译器首先执行,然后链接器完成其工作并调用编译器来解析未解决的内容(内联/模板...)
链接地址: http://www.djcxy.com/p/29795.html上一篇: Why are C++ inline functions in the header?
下一篇: Why is the C++ STL is so heavily based on templates? (and not on *interfaces*)