本文已参与[新人创作礼]活动,一起开启掘金创作之路。
(欢迎大家关注我的微信公众号——控制工程研习,上面会分享很多我学习过程中总结的笔记。)
1. 什么是内联函数
C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。
对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。
如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。
在类定义中的定义的函数都是内联函数,即使没有使用inline 说明符。
2. 内联函数的作用
引入内联函数的目的是为了解决程序中函数调用的效率问题,程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。
3. 内联函数的使用场合
首先使用inline函数可以完全取代表达式形式的宏定义。
内联函数在C++类中应用最广的,应该是用来定义存取函数。我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把这些读写成员函数定义成内联函数的话,将会获得比较好的效率。
例如下面的代码:
class A
{
private:
int nTest;
public:
int readTest(){
return nTest;
}
void setTest(int i);
};
inline void A::setTest(int i){
nTest = i;
};
类A的成员函数readTest()和setTest()都是inline函数。readTest()函数的定义体被放在类声明之中,因而readTest()自动转换成inline函数;setTest()函数的定义体在类声明之外,因此要加上inline关键字。
4. 为什么不把所有的函数都定义成内联函数
内联是以代码膨胀(复制)为代价的,仅仅省去了函数调用的开销,从而提高函数的执行效率。 如果执行函数体内代码的时间相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
(3)另外,类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。
所以不要随便地将构造函数和析构函数的定义体放在类声明中。一个好的编译器将会根据函数的定义体,自动取消不值得的内联(这说明了inline不应该出现在函数的声明中)。
5. 内联函数与宏有什么区别
(1)内联函数在编译时展开,宏在预编译时展开。
(2)在编译的时候,内联函数可以直接被镶嵌到目标代码中,而宏只是一个简单的文本替换。
(3)内联函数可以完成诸如类型检测、语句是否正确等编译功能,宏就不能具有这样的功能。
(4)宏不是函数,inline函数是函数。
(5)宏在定义时要小心处理宏参数(一般情况是把参数用括号括起来),否则容易出现二义性。而内联函数定义时不会出现二义性。