在 C 语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么在 C++ 中有没有相同的技术或者更好的实现方法呢?答案是有的,那就是内联函数。内联函数作为编译器优化手段的一种技术,在降低运行时间上非常有用。我们将从:
这四个方面对内联函数进行介绍。
内联函数是 C++ 的增强特性之一,用来降低程序的运行时间。当内联函数收到编译器的指示时,即可发生内联:编译器将使用函数的定义体来替代函数调用语句,这种替代行为发生在编译阶段而非程序运行阶段。
值得注意的是,内联函数仅仅是对编译器的内联建议,编译器是否觉得采取你的建议取决于函数是否符合内联的有利条件。如何函数体非常大,那么编译器将忽略函数的内联声明,而将内联函数作为普通函数处理。
定义函数时,在函数的最前面以关键字“ inline ”声明函数,即可使函数称为内联声明函数。
例如:
Class A { Public: inline int add(int a, int b) { return (a + b); }; }
Class A { Public: int add(int a, int b); };
inline int A::add(int a, int b) { return (a + b); }
有时候我们会写一些功能专一的函数,这些函数的函数体不大,包含了很少的执行语句。例如在计算 1~1000 以内的素数时,我们经常会使用开方操作使运算范围缩小,这时我们会写一个函数:
int root(int n) { return (int)sqrt((float)n); }
然后我们的求范围内素数的函数可以这样写。
int prime(int n) { int i; for (i = 2; i <= root(n); i++) { if (n%i == 0) return 0; return 1; } }
当然,把 root 函数放在循环中不是个不明智的选择,但想象一下,在某个程序上下文内必须频繁地调用某个类似 root 的函数,其调用函数的花销会有多大:当遇到普通函数的调用指令时,程序会保存当前函数的执行现场,将函数中的局部变量以及函数地址压入堆栈,然后再将即将调用的新函数加载到内存中,这要经历复制参数值、跳转到所调用函数的内存位置、执行函数代码、存储函数返回值等过程,当函数执行完后,再获取之前正在调用的函数的地址,回去继续执行那个函数,运行时间开销简直太多了。
C++内联函数提供了替代函数调用的方案,通过inline声明,编译器首先在函数调用处使用函数体本身语句替换了函数调用语句,然后编译替换后的代码。因此,通过内联函数,编译器不需要跳转到内存其他地址去执行函数调用,也不需要保留函数调用时的现场数据。
通过下面这些优缺点总结你大概会更理解为什么要使用 inline 函数:
优点:
缺点:
当程序设计需要时,每个函数都可以声明为 inline 。下面列举一些有用的建议:
关键点