一、为什么要引入内联函数
引入内联函数的主要目的是,用它代替C语言中表达式形式的宏定义。C语言中可以使用宏定义:
#define SUM(a, b) (a+b)*(a-b)
这种宏定义在形式上像一个函数,但它没有了参数压栈,代码生成等一系列操作,因此效率很高。这种宏定义在形式上类似于函数,但在使用时仅仅只是做预处理器符号表中的简单替换,因此不能进行参数有效性的检测,另外,其返回值也不能被强制转换,有着很多隐患和局限性。
另外,c++引入了类和类的访问控制,这样,如果一个操作涉及类的保护成员或私有成员,就不能使用这种宏定义的方式实现。inline的出现就是为了取代这种表达式宏定义,消除了其缺点,同时继承了其优点。
二、为什么inline能很好地取代表达式宏定义
原因:
(1)inline定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换(像宏一样展开),没有调用的开销,效率很高。
(2)内联函数也是一个真正的函数,编译器在调用一个内联函数时,首先会检查它的参数类型,保证调用正确;然后进行一系列的相关检查,就像对待任何一个真正的函数,消除了它的隐患和局限性。
(3)inline可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。
三、内联函数的使用场合
首先,inline函数可以完全取代表达式形式的宏定义。内联函数在c++中使用非常广,用于定义存取函数,将类中的读写成员函数定义为inline函数,可以访问类中的私有和保护成员,而且其效率会比较好。
class A
{
int m_Test;
public:
int readTest()
{
return m_Test;
}
void setTest(int i);
};
inline void A::setTest()
{
m_Test = i;
}
类A中的readTest和setTest函数都是inline函数,readTest函数定义在类中,因而自动转化为inline函数,setTest函数定义在类外,所以要加inline关键字。
四、为什么不把所有的函数定义成内联函数
内联是以代码复制为代价的,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行代码的时间比函数调用的时间大很多,那么效率收获会很小,其次,内联函数的代码存放于内存,会消耗很多空间。
以下几种情况不宜使用内联函数:
(1)如果函数体内代码较长,使用内联函数导致内存消耗较高。
(2)如果函数体内存在循环体内,那么执行函数的时间比调用函数的开销大。
(3)类的构造和析构函数容易让人误会成使用内联更有效,要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷的”执行了基类的构造和析构函数。
因此,不要随便把构造和析构函数的定义体放在类声明中,一个好的编译器将会根据函数的定义体,自动取消不值得的内联。
五、内联函数与宏有什么区别
区别如下
(1)内联函数在编译时展开,宏在预编译时展开。
(2)在编译的时候,内联函数可以直接被嵌到代码中,而宏只是一个简单的文本替换,
(3)宏不是函数,inline是函数
(4)宏在定义时要小心处理宏参数,否则容易出现歧义,而内联函数没有这个问题