【C++基础之十五】内联函数
1.优点
为什么使用内联函数,而不使用宏定义,虽然宏本身采用的展开来替代函数调用的压栈出栈返回等操作,提高了代码的效率,但是会有两个问题:
(1)边际效应
宏只是展开代码而已,所以在一些操作符的优先级问题使用上很容易出现异常。
#define ADD(x,y) x+y; int _tmain(int argc, _TCHAR* argv[]) { cout<<3*ADD(1,2); return 0; }
原意是要输出9,而实际上由于直接展开的关系,输出值为5。
(2)无法操作类的私有变量
2.原理
对于任何内联函数,编译器在符号表里放入函数的声明(包括名字、参数类型、返回值类型)。如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。在调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样)。如果正确,内联函数的代码就会直接替换函数调用,于是省去了函数调用的开销。
3.实现
3.1.inline声明
inline声明应该修饰在函数的定义,而不是函数的声明。
class A { public: void f(); }; inline void A::f()//在定义中添加inline修饰符 { cout<<"f()"; } int _tmain(int argc, _TCHAR* argv[]) { A a; a.f(); return 0; }
3.2.定义在类内的成员函数自动为内联函数
尽管没有inline修饰符,在类内进行定义的成员函数也是内联函数。
class A { public: inline void f(){cout<<"f()";};//类内定义自动为内联函数 }; int _tmain(int argc, _TCHAR* argv[]) { A a; a.f(); return 0; }
4.注意
那既然内联函数能提高效率,怎么不把所有的函数定义为内联?
注意,内联函数可以节省函数调用花费的时间,但是它是以代码复制为代价的,如果花费在函数体内的时间大于函数调用的时间,那是得不偿失的。
以下两种情况,慎重内联函数:
(1)函数体代码很长,每一处的内联都要进行代码的复制,对内存和速度消耗都是很大的。
(2)函数体内循环,那么执行的时间也会比函数调用的时间大。
正常情况下编译器会自动取消不值得内联的函数。