函数的劣势
调用函数一般比求等价表达式的值要慢一些,在大多数机器上一次函数调用其实包含着一系列工作:
- 调用前要先保存寄存器,并在返回时恢复
- 可能需要拷贝实参
- 程序转向一个新的位置继续执行
简介
Tips:内联机制用于优化规模较小、流程直接、频繁调用的函数。很多编译器都不支持内联递归函数,而且一个75行的函数也不大可能在调用点内联地展开。
使用内联函数可以避免函数调用的开销,它会在每个调用点上“内联地”展开。
inline const string& shorterString(const string &s1, const string &s2) {return s1.size() <= s2.size() ? s1 : s2;}
定义在头文件中
和其他函数不同,内联函数可以在程序中多次定义。毕竟编译器想要展开函数仅有函数声明时不够的,还需要函数的定义。由于对于某个给定的内联函数来说,它的多个定义必须完全一致,基于这个原因内联函数通常定义在头文件中。
定义在类内部的函数是隐式的内联函数
Tips:和我们在头文件中定义inline函数的原因一样,inline成员函数也应该与相应的类定义在同一个头文件中。
在类中常有一些规模较小的函数适合于被声明成内联函数,其中定义在类内部的成员函数和友元函数是自动inline的,在类的外部我们可以用inline关键字修饰函数定义将其显式声明为内联函数。
声明为内联的函数也不一定会被编译器内联
有些函数即使被声明为内联的也不一定会被编译器内联,比如虚函数和递归函数就不会被正常内联:
- 递归层数在编译时可能是未知的,因此大多数编译器都不支持内联递归函数
- 用类指针调用虚函数时不会被内联展开,因为此时编译器还不知道运行时哪个函数会被调用
