第九章 内联函数
为了解决C中不太方便,且容易出错的宏定义的问题,C++中使用内联函数来代替。内联函数有三大优点:1) 增加了参数检查,保证了代码的正确性 2) 仍然像C中一样,内联函数在调用处展开,而不是像普通函数一样需要压栈,RETURN等返回,减少了函数调用的开销。3)能像一般的成员函数一样可以在类里访问自如。
一、预处理器的缺陷
#define F (x) (x+1)
F(1)
(x) (x+1)(1)
看上面这段代码,程序员的本意应该是想定义一个函数F(x)实现一个将参数x加1的操作,为了方便,他将其定义为一个宏定义。F (x)之间,请注意,是有空格的。这样F(1)将被替代成(x) (x+1)(1),而不是我们预想的(1+1)。对于看似像函数的宏定义可能产生的意想不到的错误,稍有经验的程序员应该早有领教。
二、宏和访问
class X
{
int i;
public:
#define VAL(X::i) //Error
};
上面这段代码,想在类X中定义一个与类X的数据成员I有关的类似函数的宏定义。然而这是不可能的,宏定义只执行简单的代码替换工作,预处理器也不可能知道X与I的关系。程序设计者出于效率考虑,不得不让一些数据成员成为public类型,这就会暴露内部实现并妨碍在这个实现中的改变,从而消除了private提供的保护。
三、内联函数
在C++中,宏的概念是通过内联函数来实现的,而内联函数无论从那一方面来说,都是真正的函数。内联函数与普通函数唯一不同的地方是它在适当的地方像宏一样展开,而不需要函数调用的开销。
重要结论:任何在类中定义的函数自动成为内联函数,但也可以在非类的函数前面加上inline关键字使之成为内联函数。但必须在声明和定义时同时注明inline关键字。如
inline int plusOne(int x);
inline int plusOne(int x)
{
return ++x;
}
编译器将检查函数参数列表使用是否正确,并返回值。这些事情是预处理器无法完成的。内联函数的声明一般放在头文件里面。
请记住:使用内联函数的目的是减少函数调用开销。但是如果函数较大,,由于需要在调用函数的每一处重复赋值代码,这样将使得代码膨胀,在速度方面获得的好处就会减少。
1、访问函数
在类中内联函数的最重要的使用之一就是访问函数(access function)。这就是一般所谓的setter和getter函数,提供类中私有数据成员的访问。如下:
Class Access
{
int i;
public:
int read() const
{
return i;
}
void set(int ii)
{
i = ii;
}
};
int main()
{
Access A;
A.set(100)'
int x = A.read();
return 0;
}