内联函数
当我们将sum的调用点写在另外一个cpp中,并在前面加上inline关键字后,我们会发现运行失败。
inline int sum(int a, int b)
// inline函数将不生成符号
{
return a + b;
}
int sum(int, int);
int main()
{
std::cout << "sum:" << sum(10,20) << std::endl;
return 0;
}
此时程序运行失败,原因:inline函数是不生成符号的,它在编译阶段将代码展开,所以在进行符号解析时,我们将无法获得调用点所生成的符号
那我们知道宏的处理也是带调用点直接展开进行文本替换,那这两个直接有什么区别呢?
首先相同点:宏的处理和inline关键字都是在调用点直接展开的
不同点:inline函数是在编译阶段展开,它是有类型检查和安全检查的;而宏是在预编译阶段展开,它没有进行相关的安全检查,直接进行文本替换。所以inline函数先对于宏来说是比较安全的。我们也可以认为inline是一种更加安全的宏。
那inline和static又有什么区别呢?
1.inline是直接在调用点进行代码展开的,就少了相应的开栈和清栈的过程。而static是需要进行开栈与清栈的。
2.inline不生成符号,static是生成符号的。
既然inline有这么多的优点,那我们为什么不把所有的宏和static替换成inline呢,当然是它也有一些缺点的:比方说我们在inline中写了20行代码,这时有5个源文件来调用我们的inline函数,每个函数都会调用5次我们的inline。那就是说我们的inline总共要调用25次,即500行的代码量。而其中的480行代码都是重复的代码。那么可想而知我们最终生成的.o文件就会特别的大。这样的空间换时间的方法,无疑是捡了芝麻丢了西瓜,是得不偿失的行为。
注意,inline函数在debug版本中是不生效的,尽管我们加上了inline,但是它任然会开辟空间。
总结:
1.inline只在release版本生效,它在debug版本是不生效的
2.inline只是给编译器的一个建议在递归,循环中,将不会处理
3.inline基于实现的,而不是基于声明,需要有函数体
4.inline的实现要写在头文件中,写在源文件中没有调用点,代码无法展开
写在头文件中,当我们要用到这个头文件,就会代码展开