C++内联函数

:就是使用一个字符串来代替一个表达式代码或函数调用代码;编译之前,预处理器会使用这个宏字符串所代表的表达式代码或函数调用代码来替换所有出现的宏字符串,这样的话,用宏表示的函数调用代码就不用另外开辟函数栈,不用保护和恢复函数调用现场,这样就提高了代码的执行效率;所以,调用一个宏比调用一个函数更有效;
但是调用宏的时候,有一个缺点:由于宏在预处理时使用的是宏字符串替换,所以,编译器在编译的时候不知道宏所代表的代码的语法,不知道宏所代表的代码的数据类型,没有安全检查;如果出现的类里面,宏不能访问类的私有成员,而且容易产生二意性;所以,宏也有自己不能解决的、不可避免的问题;
解决宏定义函数所带来的问题的办法,就是使用内联函数;可以使用内联函数来代替宏定义;

内联函数与宏的区别在于:宏是由预处理器来对宏进行替代,没有语法检查、类型检查和安全检查;内联函数是通过编译器的控制来实现的,有语法检查、类型检查和安全检查;内联函数是真正的函数,而且在调用的地方,由编译器负责把内联函数的函数体代码块替换到内联函数被调用的地方,这一点与宏替换很相似;内联函数有参数,有返回值;由于内联函数可以像宏一样被展开,所以调用内联函数的时候,取消了函数参数压栈、出栈所带来的开销,从而减少了函数调用开销;这就是内联函数的优越于宏的地方;

内联函数的声明和内联函数的函数体的定义必须在一起;下面声明内联函数的语句是无效的:

inline int Max(int a, int b);

而下面的内联函数的定义是有效的:

inline int Max(int a, int b){return  ((a > b) ? a : b)};


inline的原理:代码替代

       在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替代。

       例如,如果一个函数被指定为inline 函数则它将在程序中每个调用点上被内联地展开例如

[cpp]  view plain copy
  1. int minVal2 = min( i, j );  
在编译时被展开为
[cpp]  view plain copy
  1. int minVal2 = i < j << i : j;  
 则把min()写成函数的额外执行开销从而被消除了。

3、inline的使用

       让一个函数成为内联函数,隐式的为在类里定义函数,显式的则是在函数前加上inline关键字说明。

4、使用inline的一些注意事项

      a.从inline的原理,我们可以看出,inline的原理,是用空间换取时间的做法,是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。所以,如果函数体代码过长或者函数体重有循环语句,if语句或switch语句或递归时,不宜用内联

      b.关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。内联函数调用前必须声明。《高质量C/C++编程》里一个例子。

[cpp]  view plain copy
  1. inline void Foo(int x, int y); // inline 仅与函数声明放在一起  
  2. void Foo(int x, int y)  
  3. {  
  4.     ...  
  5. }  
以上代码不能成为内联函数,而以下则可以

[cpp]  view plain copy
  1. void Foo(int x, int y);  
  2. inline void Foo(int x, int y) // inline 与函数定义体放在一起  
  3. {  
  4.     ...  
  5. }  
       所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。对于以上例子,林锐还建议,只在定义前加上inline,而不是在声明和定义前都加,因为这能体现高质量C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈。

       c.inline对于编译器来说只是一个建议,编译器可以选择忽略该建议。换句话说,哪怕真的写成了inline,也没有任何错误的情况下,编译器会自动进行优化。所以当inline中出现了递归,循环,或过多代码时,编译器自动无视inline声明,同样作为普通函数调用。


总结下:

       楼主觉得可以将内联理解为C++中对于函数专有的宏,对于C的函数宏的一种改进。对于常量宏,C++提供const替代;而对于函数宏,C++提供的方案则是inline。在C中,大家都知道宏的优势,编译器通过复制宏代码的方式,省去了参数压栈,生成汇编的call调用,返回参数等操作,虽然存在一些安全隐患,但在效率上,还是很可取的。

       不过函数宏还是有不少缺陷的,主要有以下:

       a.在复制代码时,容易出现一想不到的边际效应,比如经典的

[cpp]  view plain copy
  1. #define MAX(a, b) (a) > (b) ? (a) : (b)  
在执行语句:
[cpp]  view plain copy
  1. result = MAX(i, j) + 2 ;  
时,会被解释为

[cpp]  view plain copy
  1. result = (i) > (j) ? (i) : (j) + 2 ;  
     b.使用宏,无法进行调试,虽然windows提供了ASSERT宏

     c.使用宏,无法访问类的私有成员
      所以,C++ 通过内联机制,既具备宏代码的效率,又增加了安全性,还可以自由操作类的数据成员,算是一个比较完美的解决方案。

转载出处:

http://bdxnote.blog.163.com/blog/static/844423520087271033648/

http://blog.csdn.net/coder_xia/article/details/6723387

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值