inline内联函数话题
/*
*运行平台:Visual Studio 2015
*参考资料:《C++ Primer Plus(第6版)》,传智扫地增C++基础课程
*/
目录
一、前言
在讲inline内联函数之前,先问大家一个
问题:C++中的const常量可以在一定程度上替代宏常数定义,那么是否有解决方案替代宏代码片段呢?
回答:肯定有的,毕竟C++是对C的升级嘛,C++中推荐使用内联函数替代宏代码片段。
二:那么怎么使用呢?
在C++中使用inline关键字声明内联函数,声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。如:inline void get();
三、注意
1、内联函数生成的代码中是没有定义的
C++编译器直接将函数体插入在函数调用的地方 ,内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)。
因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。
inline void get()
{
printf("Hello\n");
}
int main()
{
get();
/* 相当于 */
{
printf("Hello\n");
}
}
2、C++编译器不一定准许函数的内联请求
内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)。内联函数是对编译器的一种请求,既然是请求,那么肯定可以拒绝,因此编译器可能拒绝这种请求。
3、inline与宏代码片段区别
内联函数由编译器处理,直接将编译后的函数体插入调用的地方。
宏代码片段由预处理器处理, 进行简单的文本替换,没有任何编译过程。
4、C++编译器能够进行编译优化
现代C++编译器能够进行编译优化,因此一些函数即使没有inline声明,也可能被编译器内联编译。
5、C++中内联编译的限制
- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞大
- 不能对函数进行取址操作
- 函数内联声明必须在调用语句之前
6、inline替代宏代码片段就可以避免宏的副作用
用一段程序来说明:
#include "iostream"
using namespace std;
#define MYFUNC(a, b) ((a) < (b) ? (a) : (b))
inline int myfunc(int a, int b)
{
return a < b ? a : b;
}
int main()
{
int a = 1;
int b = 3;
int c = myfunc(++a, b);
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
c = MYFUNC(++a, b);
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
system("pause");
return 0;
}
结果:可以看到两者执行的结果不一致,因此使用#define定义代码块时可能会造成一定的副作用。
解释:
结论:
- 内联函数在编译时直接将函数体插入函数调用的地方。
- inline只是一种请求,编译器不一定允许这种请求。
- 内联函数省去了普通函数调用时压栈,跳转和返回的开销。