内联函数详解--C++

论坛 期权论坛 脚本     
匿名技术用户   2020-12-28 15:14   126   0

C++中引入内联函数主要是可以解决使用宏带来的问题。

在C中,保持效率的一个方法是使用宏。预处理器直接用宏代码代替宏调用,就没有了参数压栈、生成汇编语言的CALL、返回参数、执行汇编语言的RETURN等开销。但是在C++中使用预处理器存在连个问题:

(1)宏看起来像一个函数调用,但并不总是这样,它隐藏了难以发现的错误(C中也存在);

宏只是简单的字符替换,如果宏调用中使用表达式作为参数的时候,就会出现问题。

#define F (x) (x + 1)

这个问题可以通过在宏定义的各个地方加上括号来保证优先级。但如果出现问题,将很难发现。

(2)预处理不允许访问成员函数(C++特有)。

在C++中,宏的概念是作为内联函数来使用的。内联函数能够像我们期望的任何函数一样具有我们所期望的任何行为,唯一不同的是内联函数在适当的地方像宏一样展开,所以不需要函数调用的开销。

在任何类中定义的函数自动成为内联函数(不用加关键词inline)。非类的函数面前加上关键字inline也能使之成为内联函数,但必须是函数体和声明结合在一起,否则编译器将它作为普通函数对待。

inline int add(int a,int a);

没有任何效果,仅仅只是函数声明,必须写成如下的方式:

inline int add(int a,int b){
    return a+b;
}

内联函数和编译器

当编译器遇到一个内联函数时,编译器在它的符号表里放入函数类型(函数名+参数类型+返回类型),当编译器看到内联函数体进行分析没有发现错误时,就将函数体的代码也放入符号表。当调用一个内联函数时,编译器首先确保调用正确,即所有参数类型要与函数参数表中的参数类型一致(或者能转换成正确的类型),返回值类型正确。这是与预处理器显著不同的地反个,因为预处理器不能检查类型和进行转换。如果所有的函数类型信息符合调用,内联函数代码就会直接替换函数调用,这消除了调用的开销。

以下两种情况不能执行内联:

(1)函数太复杂,调用内联就会将函数代码全部插入调用的地方,导致代码膨胀,而程序没有任何显著改进。内联是编译器的一个建议,编译器不会强迫内联任何代码。一个好的编译器会内联小的、简单的函数,同时明智的忽略太复杂的函数。

(2)显式或者隐式去函数地址,编译器不能执行内联。

在C++的大型项目中.h文件中声明函数,在.cpp文件中定义就可以。一个文件的小程序(main函数文件)中直接用关键字inline定义成员函数即可。


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP