写点什么

inline 函数的基本应用讨论

作者:老王同学
  • 2023-02-27
    广东
  • 本文字数:1611 字

    阅读完需:约 5 分钟

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 函数,编译器会实现为内联调用,在性能方面甚至高于普通的函数调用。

发布于: 刚刚阅读数: 4
用户头像

老王同学

关注

还未添加个人签名 2020-04-30 加入

还未添加个人简介

评论

发布
暂无评论
inline函数的基本应用讨论_c++_老王同学_InfoQ写作社区