inline函数的基本应用讨论
2012-06-23 11:28
190 查看
1 inline函数的定义
一般来说,内联机制适用于优化小的、只有几行的而且经常被调用的函数。
什么情况下编译器有可能会真正让你的函数成为内联呢?
(1) 函数显式声明为inline;
(2) 函数定义在class定义内部;
呃,原则上inline函数只能定义在头文件中,虽然定义在class内部的也是inline函数,而class却也可以定义在cpp文件中……
inline函数体有个条件最好要满足:函数体非常简单,比如只有一个renturn语句。不过即使这个条件满足了,这个函数最终如何实现,会不会真正的内联,仍然取决于编译器。
2 使用inline取代宏
C语言中的宏有时候是个比较好用的东西, 但在C++中不推荐使用预处理功能, 宏, 在C++中都可以找到对应的替代物.比如下面的例子.
计算两个对象的最大值:
#define max(a,b) ((a) > (b) ? (a) : (b))
这个语句有很多缺陷,想想都让人头疼。象这样的宏,你必须记住对每个参数都要加上括号;否则,别人调用你的宏时如果用了表达式,就会造成很大的麻烦。但是即使你加了括号,还会有象下面这样奇怪的事发生:
int x = 5, y = 0;
max(++x, y); // x 的值增加了2次
max(++x, y+10); // x 的值只增加了1次
这种情况下,max内部发生些什么,取决于它比较的是什么值!这样的代码大家应该趁早敬而远之。
幸运的是你不必再忍受这样愚笨的语句了。内联函数可以用普通函数实现宏的效率,再加上可预计的行为和类型安全:
inline int max(int a, int b){return a > b ? a : b; }
这个函数可没有什么奇怪的事情发生了。(1)函数会对参数进行类型检查;(2)函数的参数不会对其调用时传入的表达式重复计算。
这个版本的max只能处理int类型。我们把这个话题再延伸一下, 使用模板可以很轻巧地解决这个问题:
template<class T>
inline const T& max(const T& a,constT& b)
{ return a > b ? a : b; }
这个模板产生了一整套函数,每个函数拿两个可以转换成同种类型的对象进行比较,然后返回较大的(常量)对象的引用。因为不知道T的类型,返回时传递引用可以提高效率。不要奇怪,模板函数也可以定义为inline,注意一下其定义的语法形式,inline关键字放在template之后,函数返回值之前。
内联函数的基本思想是将每个函数调用,用它的代码体来替换,这样一来,内联函数看起来像函数,运行起来也像函数,但使用时无需承担函数调用的开销。不要小看inline函数的优势,它具有和宏一样的效率,但是#define的宏展开,只是单纯的代码字符串替换,而inline函数是可以检查你传入的参数的。
当然凡事没有绝对。内联函数如果调用的地方太多,或者其本身函数体的代码过多,可能会增加整个目标代码的体积。而且更重要的是,inline这个指令,它只是给编译器的一种提示,编译器不一定必须这么做,当内联函数包含循环和递归等比较复杂的代码时,编译器八成会忽略掉inline,更不用提虚函数了。所以这个语言特性是依赖于编译器的,使用的时候就需要特别注意了。
3 inline在函数对象中的应用
函数对象,本来是由重载了函数调用操作符operator()而衍生出来的概念,但是函数对象在C++中的应用却非常广泛,对C++程序设计思想的贡献非同小可。
如果一个类的对象具有operator()运算符,这个对象活动起来就像函数,我们就称它为一个函数对象,它可以像一个函数一样使用。有的书中称这种函数形式为仿函数。
例如这个Add类:
将它用到加法运算中,和调用函数的效果是一样的。例如:
由于operator()这个函数一般情况下也相当的短小精悍,且其定义也位于class内部,所以可以认为它也是inline函数,编译器会实现为内联调用,在性能方面甚至高于普通的函数调用。
一般来说,内联机制适用于优化小的、只有几行的而且经常被调用的函数。
什么情况下编译器有可能会真正让你的函数成为内联呢?
(1) 函数显式声明为inline;
(2) 函数定义在class定义内部;
呃,原则上inline函数只能定义在头文件中,虽然定义在class内部的也是inline函数,而class却也可以定义在cpp文件中……
inline函数体有个条件最好要满足:函数体非常简单,比如只有一个renturn语句。不过即使这个条件满足了,这个函数最终如何实现,会不会真正的内联,仍然取决于编译器。
2 使用inline取代宏
C语言中的宏有时候是个比较好用的东西, 但在C++中不推荐使用预处理功能, 宏, 在C++中都可以找到对应的替代物.比如下面的例子.
计算两个对象的最大值:
#define max(a,b) ((a) > (b) ? (a) : (b))
这个语句有很多缺陷,想想都让人头疼。象这样的宏,你必须记住对每个参数都要加上括号;否则,别人调用你的宏时如果用了表达式,就会造成很大的麻烦。但是即使你加了括号,还会有象下面这样奇怪的事发生:
int x = 5, y = 0;
max(++x, y); // x 的值增加了2次
max(++x, y+10); // x 的值只增加了1次
这种情况下,max内部发生些什么,取决于它比较的是什么值!这样的代码大家应该趁早敬而远之。
幸运的是你不必再忍受这样愚笨的语句了。内联函数可以用普通函数实现宏的效率,再加上可预计的行为和类型安全:
inline int max(int a, int b){return a > b ? a : b; }
这个函数可没有什么奇怪的事情发生了。(1)函数会对参数进行类型检查;(2)函数的参数不会对其调用时传入的表达式重复计算。
这个版本的max只能处理int类型。我们把这个话题再延伸一下, 使用模板可以很轻巧地解决这个问题:
template<class T>
inline const T& max(const T& a,constT& b)
{ return a > b ? a : b; }
这个模板产生了一整套函数,每个函数拿两个可以转换成同种类型的对象进行比较,然后返回较大的(常量)对象的引用。因为不知道T的类型,返回时传递引用可以提高效率。不要奇怪,模板函数也可以定义为inline,注意一下其定义的语法形式,inline关键字放在template之后,函数返回值之前。
内联函数的基本思想是将每个函数调用,用它的代码体来替换,这样一来,内联函数看起来像函数,运行起来也像函数,但使用时无需承担函数调用的开销。不要小看inline函数的优势,它具有和宏一样的效率,但是#define的宏展开,只是单纯的代码字符串替换,而inline函数是可以检查你传入的参数的。
当然凡事没有绝对。内联函数如果调用的地方太多,或者其本身函数体的代码过多,可能会增加整个目标代码的体积。而且更重要的是,inline这个指令,它只是给编译器的一种提示,编译器不一定必须这么做,当内联函数包含循环和递归等比较复杂的代码时,编译器八成会忽略掉inline,更不用提虚函数了。所以这个语言特性是依赖于编译器的,使用的时候就需要特别注意了。
3 inline在函数对象中的应用
函数对象,本来是由重载了函数调用操作符operator()而衍生出来的概念,但是函数对象在C++中的应用却非常广泛,对C++程序设计思想的贡献非同小可。
如果一个类的对象具有operator()运算符,这个对象活动起来就像函数,我们就称它为一个函数对象,它可以像一个函数一样使用。有的书中称这种函数形式为仿函数。
例如这个Add类:
class Add { public: int operator()(intv1, int v2) { return v1 + v2; } };
将它用到加法运算中,和调用函数的效果是一样的。例如:
int a1 = 3, a2 = 1; Add add; //定义函数对象 cout << add(a1, a2) << endl; //调用add.operator(a1, a2)
由于operator()这个函数一般情况下也相当的短小精悍,且其定义也位于class内部,所以可以认为它也是inline函数,编译器会实现为内联调用,在性能方面甚至高于普通的函数调用。
相关文章推荐
- MySQL中函数、游标、事件、视图基本应用举例(代码)
- atexit函数基本应用
- (转)内联(inline)函数与虚函数(virtual)的讨论
- Python基本语法_函数属性 & 参数类型 & 偏函数的应用
- C++ replace()函数基本应用方法总结
- lua 的基本数据类型和函数应用 . :符号的区别
- Oracle基本函数的应用
- const, static, inline函数在类外定义时注意点讨论
- matlab在DSP中的应用(一)---基本函数
- c#基本函数应用1
- C++ inline 函数正确应用方法介绍
- c#基本函数应用2
- Linux基本网络配置和脚本编程中函数的应用
- 函数BAPI_MATERIAL_SAVEDATA基本应用示例
- POJ3080 基本字符串库函数的应用 ..Brute Force/朴素模式匹配算法
- string.h中的函数和基本应用
- 初时OpenGL,OpenGL应用工具包GLUT的基本函数
- VxWorks应用开发基本步骤和函数taskPriorityGet()
- 基本语言细节--inline函数的几点分析
- 内联(inline)函数与虚函数(virtual)的讨论