一:什么是内联函数
学习C++时,一般先掌握的是有返回值的,带参或不带参的常规函数,但与之相对的还有所谓的内联(inline)函数。要了解什么是内联函数以及其与常规函数的区别,需要对程序有更深刻的理解。
当编译结束以后生成由一组机器语言指令组成的可执行程序(.exe),而运行程序时操作系统将指令载入到每条指令对应的内存中,随后计算机将逐步执行程序。如果你已经学过汇编语言,那你应该很熟悉执行时的跳转操作:当执行循环或分支语句时,将跳过一些指令向前或向后跳转特定的指令地址。
在常规函数执行时,执行到函数调用指令,程序将储存该指令的内存地址,将函数参数复制到堆栈,跳转到标记函数起点的内存单元执行函数代码,将返回值放入寄存器中然后跳转回到地址被保存的指令处。也就是说常规函数的调用需要来回跳转并记录跳转地址,这些操作需要一些开销(或者说增加了程序执行时间)。
而内联函数与之不同的是,编译器用对应的函数代码替换函数调用指令。也就是说直接顺序执行指令即可而不需要跳转到其他地址执行代码。因此内联函数的执行速度相较于常规函数较快。但是问题是,当程序多次调用目标函数时,那么使用内联函数将意味着让程序包含多个函数拷贝,这将占用更多的内存。接下来以用一张图简单的描述内联函数以及常规函数的区别:
实际上,应当有选择的使用内联函数,如果调用函数的代码很短,那么对应的执行时间就会少于处理代码调用所用时间,那么内联调用就会节省时间;相反的,如果处理代码的时间长于或远长于处理跳转所用时间,那么使用内联函数就只能降低少部分时间但大大增加所用内存。同时,由于处理代码调用时间本身不长,除非这个函数经常被调用,那么使用内联函数所节省时间不会太多。
二:如何使用内联函数
欲将一个常规函数变化为内联函数,那么需要在函数的声明和定义时在之前加上关键字inline即可。例如下面的代码范例:
#include <iostream>
using namespace std;
inline double square(double x){return x*x;} //定义内联函数
int main(){
int a = 10;
cout<<square(a);
return 0;
}
三:内联函数在类中的运用
在进行类编程时,常常将类声明和函数原型等放到头文件(.h)中,将函数定义放在另一个CPP文件中。定义于类声明中的函数都将自动成为内联函数,而编写程序时常常将代码长度短小的函数作为内联函数。如果愿意,也可以使用inline关键字在类声明以外的地方声明内联函数。比如下面这段示例代码:
#include <iostream>
using namespace std;
class Numbers{
private:
int pro;
int square;
void set_squ(){square = pro*pro;} //定义在类声明中的函数自动成为内联函数
public:
void set_pro(int a);
void show();
};
/*或者在定义函数时加上inline关键字
inline void Numbers::set_squ(){
square = pro*pro;
}*/
void Numbers::set_pro(int a){
pro = a;
set_squ(); //不需要跳转即可调用set_squ()函数
}
void Numbers::show(){
cout<<"square of "<<pro<<" is "<<square;
}
int main(){
Numbers num;
num.set_pro(10);
num.show();
}