内联函数在很多人看来并不是很起眼,但是我依稀记得当时自己在学校里去QG工作室面试时,师兄就问到内联函数和宏有什么区别。最近,自己在搞个类似QQ的点对点IM系统,在封装消息实体类时,由于消息实体类中的读写成员函数使用的频率比较高,加上这些函数的函数体比较小,经过综合考虑我就把它们设计成了内联函数。刚好自己想写点什么,今天就总结下这个小而巧的内联函数的。

     (一)在这里还是引用《C++Primer》这本书的一些内容,因为参考了很多资料,还是觉得这本书的写的最好的。在了解内联函数前,我们先看下面一个小函数的例子再引出内联函数。

  const string &shorterString(const string &s1, const string &s2)

      {

    return s1.size() < s2.size() ? s1 : s2;

  }

这样一个小操作定义一个函数其实是有很多好处的:

  • 阅读和理解函数shorterString的调用,要比读一条用等价的条件表达式取代函数调用表达式并理解它的含义要容易得多。
  • 如果要做任何修改,修改函数要比找出并修改每一处等价表达式要容易得多(尽管现在一些类似VC助手插件使修改代码方便很多,但是养成良好的编程风格还是很重要的)
  • 使用函数可以确保统一的行为,每个测试都得以用相同的方式实现。
  • 函数可以重用,不必为其他应用重写代码。

但是函数虽好,但是也有潜在的很多缺点:调用函数比求解等价表达式要慢得多。在大多数机器上,调用函数要做很多工作:调用前要先保存寄存器,并在返回时恢复;复制实参;程序还必须转向一个新的位置。正式因为这个原因,这个时候内联函数就因应而生了。

  1.内联函数避免了函数调用的开销

  将函数制定为内联函数,就是将它在程序中每个调用点上”内联“地展开。假设我们将上面的那个函数定义为内联函数,则调用cout << shorterString(s1, s2) << endl;

在编译的时候将展开为:  cout << (s1.size() < s2.size ? s1 : s2) << endl;   这样从而避免了一般函数的额外执行开销。

      如何定义内联函数:在函数前面添加关键字inline。例如:

  inline const string &shorterString(const string &s1, const string &s2)

  {

    return s1.size() < s2.size() ? s1 : s2;

  }

     注意:内联函数对于编译器来说只是一个建议而已,编译器可以选择忽略这个建议。

     一般来说,内联函数适用于优化小的,只有几行的而且经常被调用的函数。大多数编译器都不支持递归函数的内联。一个1200行的函数也不太可能在调用点内联的展开。

     2.把内联函数放入头文件

     内联函数应该在头文件中定义,这一点不同于其他函数。

     内联函数对于编译器必须是可见的,以便编译器能够在调用点内联展开该函数的代码。此时,只用函数原型是不够的。

     内联函数可能在程序中定义不止一次,只要内联函数的定义在某个源文件中只出现一次,而且在所有源文件中,其定义必须是完全相同。把内联函数的定义放在头文件中,可以确保在调用函数时所使用的定义是相同的,并且保证在调用点该函数的定义对编译器可见。这里,本人不是很理解把内联函数的定义放在头文件中,可以确保在调用函数时所使用的定义是相同的”难道定义在源文件中就不可以确保定义是相同的嚒?

posted on 2011-10-11 19:55  陈文斌_5months  阅读(267)  评论(0编辑  收藏  举报