函数的劣势

调用函数一般比求等价表达式的值要慢一些,在大多数机器上一次函数调用其实包含着一系列工作:

  • 调用前要先保存寄存器,并在返回时恢复
  • 可能需要拷贝实参
  • 程序转向一个新的位置继续执行

简介

Tips:内联机制用于优化规模较小、流程直接、频繁调用的函数。很多编译器都不支持内联递归函数,而且一个75行的函数也不大可能在调用点内联地展开。

使用内联函数可以避免函数调用的开销,它会在每个调用点上“内联地”展开。

  1. inline const string& shorterString(const string &s1, const string &s2) {
  2. return s1.size() <= s2.size() ? s1 : s2;
  3. }

定义在头文件中

和其他函数不同,内联函数可以在程序中多次定义。毕竟编译器想要展开函数仅有函数声明时不够的,还需要函数的定义。由于对于某个给定的内联函数来说,它的多个定义必须完全一致,基于这个原因内联函数通常定义在头文件中。

定义在类内部的函数是隐式的内联函数

Tips:和我们在头文件中定义inline函数的原因一样,inline成员函数也应该与相应的类定义在同一个头文件中。

在类中常有一些规模较小的函数适合于被声明成内联函数,其中定义在类内部的成员函数和友元函数是自动inline的,在类的外部我们可以用inline关键字修饰函数定义将其显式声明为内联函数。

声明为内联的函数也不一定会被编译器内联

有些函数即使被声明为内联的也不一定会被编译器内联,比如虚函数和递归函数就不会被正常内联:

  • 递归层数在编译时可能是未知的,因此大多数编译器都不支持内联递归函数
  • 用类指针调用虚函数时不会被内联展开,因为此时编译器还不知道运行时哪个函数会被调用