内联函数的作用
函数调用包含一系列工作,例如保存寄存器,并在返回时恢复,可能需要拷贝实参,程序转向一个新的位置执行等,这些工作会有一定开销,如果把函数代码在调用点上内联地展开,就可以避免这些开销,加快了程序运行速度,代价是程序体积会随着内联的次数增大。
内联函数使用时要注意的
- 内联函数应该简洁,如果语句过多,则不适合定义为内联函数,最好不要超过10行。
- 定义在类声明之中的成员函数将自动成为内联函数。
- 有些函数虽然没有使用inline定义为内联函数,但是编译Release版本时还是有可能会被内联。
- 有些函数虽然有使用inline定义为内联函数,但是编译器认为这个函数不适合内联时,可以不内联该函数。
- 内联那些包含循环或switch语句的函数得不偿失,除非那些循环或switch语句很少执行。
- 内联函数是静态行为(编译时),虚函数是动态行为(运行时),所以虚函数不能被内联。
- 由于递归函数递归层数未知,在调用点展开时有可能会无限插入代码,所以大部分编译器不支持内联递归函数。
- 由于编译器在调用点内联展开函数代码时,必须找到函数的定义才能将函数调用替换为函数代码,所以头文件中仅有内联函数声明是不够的(inline关键字必须与函数定义放在一起,仅放置于函数声明前是无效的),头文件中应该有内联函数的定义,当然也可以放在源文件中,但此时只有定义的那个源文件可以用它,而且必须保证其它源文件里的同名内联函数定义是一样的(内联函数可以多次定义),那还不如放在头文件中简单。
下面代码中,inlineFunc在不同源文件中定义了两次,也被调用了两次,但是testFunc()最后输出的却是13不是7。
//Test.cpp
#include "stdafx.h"
inline int inlineFunc(int a, int b)
{
return a - b;
}
void testFunc()
{
printf("%d\n", inlineFunc(10, 3));
}
//main.cpp
#include "Test.h"
inline int inlineFunc(int a, int b)
{
return GetTickCount()? a+b:b * (a + b);
}
int main()
{
std::cout << inlineFunc(1, 2) << std::endl;
testFunc();
system("pause");
return 0;
}