内联函数小结

来源:互联网 发布:网络时时彩案件判刑 编辑:程序博客网 时间:2024/05/22 00:12

Intro:

先说调用函数的工作:先保存寄存器,并在返回时恢复,复制实参,然后转向一个新位置执行。


内联函数是为了提高函数的执行效率,用inline定义(非声明),内联函数通常就是将它在程序中的每个调用点上“内联地”展开。内联函数在编译阶段被替换。

e.g.

inline int max(int a, int b) {  return a > b ? a : b; } cout<<max(a, b)<<endl; //在编译时展开为: cout<<(a > b ? a : b)<<endl;
从而消除了把函数展开的额外开销。


内联函数和宏:

其实不建议用宏,Effictive C++第一个term就说的用inline代替宏,书中说预处理器在拷贝宏代码时会产生意想不到的边际效应;宏不可调试,而内联函数可调试;宏无法操作类的私有成员。而函数被内联后编译器可以通过上下文相关优化技术对结果代码执行更深入的优化。

书中说的边际效应不太懂,暂时没有遇到,而且已经决定inline代替宏了就不过多讨论,等遇到了来填坑。


inline函数的使用:

inline关键字必须与函数定义体放在一起才能使函数内联,仅放在函数声明前不起作用。原博主认为inline不应出现在函数声明中,因为声明和定义不可混为一谈。个人见解相同,没有遇到声明内联的,下意识直接写定义内联函数。

定义在类声明中的成员函数将自动的成为内联函数

class A {  public:  void Foo(int x, int y) { ... }   // 自动地成为内联函数  } 
但编译器是否将其视为真正内联要看Foo如何定义


内联函数应该在头文件中定义,这一点不同于其他函数。编译器在调用点内联展开函数的代码时,必须能够找到 inline 函数的定义才能将调用函数替换为函数代码,而对于在头文件中仅有函数声明是不够的。

当然内联函数定义也可以放在源文件中,但此时只有定义的那个源文件可以用它,而且必须为每个源文件拷贝一份定义(即每个源文件里的定义必须是完全相同的),当然即使是放在头文件中,也是对每个定义做一份拷贝,只不过是编译器替你完成这种拷贝罢了。但相比于放在源文件中,放在头文件中既能够确保调用函数是定义是相同的,又能够保证在调用点能够找到函数定义从而完成内联(替换)。

内联要慎用,它是以代码膨胀为代价的,函数体内代码较长不适宜内联;内部有循环或其他复杂结构不适宜内联(执行内部代码比调用函数开销大得多);谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用

如果内联函数的定义比较短小, 逻辑比较简单, 实现代码放在 .h 文件里没有任何问题. 比如, 存取函数的实现理所当然都应该放在类定义内. 出于编写者和调用者的方便, 较复杂的内联函数也可以放到 .h 文件中, 如果你觉得这样会使头文件显得笨重, 也可以把它萃取到单独的 -inl.h 中. 这样把实现和类定义分离开来, 当需要时包含对应的 -inl.h 即可。

copyright:

点击打开链接

《Effictive C++》





0 0