您的位置:首页 > 其它

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类:

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函数,编译器会实现为内联调用,在性能方面甚至高于普通的函数调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息