理解C++关键字(8)---inline内联函数

时间:2021-09-09 15:02:31

前面在总结const关键字时,曾提到:C++中几乎抛弃了宏定义,进而接受了const。对于在c语言中的宏定义关键字“#define”,确实存在着很多优势,并且在程序运行时充当了“替换”的工作。
我们知道,“#define”关键字,可以宏定义变量,也可以定义函数宏。比如#define MAX(A,B) A>B?A:B。在C++中,也提供了一个类似于函数宏的关键字“inline”。当然,它比“#define”的功能强得多,不然也不会出现。
下面详细介绍inline关键字。

1、inline的特点

首先,我们要明确,inline只是程序员(我们)向编译器提供的一个请求,而不是一个命令。因此,函数虽然在定义的时候有“inline”,但编译器并不一定以内联的方式处理该函数。什么情况下,会出现上述情形呢?我们先来看看inline的工作方式。
当我们定义一个普通函数,并在某处调用该函数时,该过程会经过保护函数入口地址、执行函数、返回等过程。而在执行一条顺序语句时,是没有保护入口地址和返回等操作的。若能向#define那样完成替换操作,又能保持函数的功能,那该多好!inline实现了
inline人在工作时,在函数调用处,将函数体以内联的方式嵌入到调用处。比如:

#include<iostream>
using namespace std;
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int m1=2,m2=3;
cout<<max(m1,m2)<<endl; //**等同于:cout<<(m1>m2?m1:m2)<<endl;**
int n1=3,n2=4;
cout<<max(n1,n2)<<endl; //**等同于:cout<<(n1>n2?n1:n2)<<endl;**
}

由以上可见,inline是以空间获取时间的。
那么,若函数体过于庞大,或函数体中有循环、递归等语句时,若在多处调用inline函数,就会使得程序占用内存增大,得不偿失。Google C++中明确指出,只有函数中语句行数小于10行时才能够使用inline。

2、内联函数的定义方式

一般内联函数有两种定义方式:

  1. 隐式定义:在类定义内部定义的成员函数(包括友元函数,但不包括构造函数和析构函数)自动成为内联函数,但在编译时是不是以内联方式进行,还要看编译器的“心情”。为什么不包括构造函数和析构函数呢?因为这两个函数经常“偷偷”的干许多我们不可见的事情,比如(可能存在类的继承、许多成员变量的初始化等)。
  2. 显示定义:即在函数定义(声明时不算,而且最好不加)时,在前面加上“inline”关键字。

综上,inline虽好,但并不完全是我们完全说了算,需要遵循编译器的想法。