一、内联函数的引入
1.在C中我们经常把一些短并且执行频繁的计算写出宏,而不是函数,这样做的理由为了提升执行效率,宏可以避免函数调用的开销,这些都由预处理过程来完成。
2.使用宏代替函数可能出现的问题
#define ADD(x,y) x+y
int main() {
int ret = ADD(10,10)*10; //我们想要得到 200
cout<<ret<<endl; //结果输出 10+10*10 = 110
return 0;
}
没有得到我们理想的结果的原因就是宏定义在预处理的时候是文本替换,所以
ret = ADD(10,10)*10,被替换后变成了:ret= 10+10*10
3.为了保持预处理宏的效率又增加安全性,而且还能像一般成员函数那样可以在类里访问自如,C++引入内联函数(inline function)
4.内联函数为了继承宏函数的效果,没有函数调用时开销,可以像普通函数那样,可以进行传参,返回值类型的安全检查,又可以作为成员函数。
二、内联函数的基本概念
1.在C++中,预定义宏的概念是用内联函数来实现的,而内联函数本身也是一个真正的函数,内联函数具有普通函数的所有行为。唯一不同之处在于内敛函数会在适当的地方像预定义宏一样展开,所以不需要函数调用的开销,因此应该不使用宏,使用内联函数。
2.在普通函数(非成员函数)函数前面加上 inline 关键字使之成为内联函数,但是函数体和声明结合必须在一起,否则编译器将它作为普通函数来对待。
inline int func(int x,int y);
以上写法没有任何效果,仅仅是声明函数,应该如下方式来做:声明和实现在一起。
inline int func(int x,int y)
{
return x+y;
}
注意:编译器将会检查函数参数列表使用是否正确,并返回值(进行必要的转换)。
使用内联函数代替宏之后:
cout<<func(10,10)*10<<endl; //等于(10+10)*10 = 200
三、内联函数注意事项
1.C++中推荐使用内联函数替代宏代码片段;
2.内联函数在最终生成的代码中是没有定义的,C++编译器直接将函数体插入在函数调用的地方,内联函数没有普通函数调用时的额外开销(压栈,跳转,返回);
3.因为内联函数在最终生成的代码中是没有定义的,所以内联函数的作用域可以理解为只在定义额文件内。也就是说在a.c中定义的 inline void func() 要在b.c中使用,则b.c中需要重新定义它;
4.inline 只是对编译器的一个内联请求,C++内联编译会有一些限制,以下情况编译器可能考虑不会将函数进行内联编译:
存在任何形式的循环语句
存在过多的条件判断语句
函数体过于庞大
对函数进行取址操作
因此,内联仅仅只是给编译器一个建议,编译器不一定会接受这种建议,如果你没有将函数声明为内联函数,那么编译器也可能将此函数做内联编译。一个好的编译器将会内联小的、简单的函数。