C++编程思想读书笔记之 第八章 内联函数

来源:互联网 发布:linux 开机运行脚本 编辑:程序博客网 时间:2024/06/05 18:03

C++编程思想读书笔记之 第八章 内联函数


内联函数的目的是为了解决程序中函数调用的效率问题。

 在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。显然,这种做法不会产生转去转回的问题,但是由于在编译时将函数休中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间代销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。


#define宏只做展开,不做检查。


C + +中,使用预处理器宏存在两个问题。

第一个问题在C中也存在:宏看起来像一个函数调用,但并不总是这样。这就隐藏了难以发现的错误。

第二个问题是C + +特有的:预处理器不容许存取私有( private )数据。这意味着预处理器宏在用作成员函数时变得非常无用。


任何在类中定义的函数自动地成为内联函数,但也可以使用inline关键字放在类外定义的函数(类的成员函数或非成员函数)前面使之成为内联函数。但为了使之有效,必须使函数体和声明结合在一起,否则,编译器将它作为普通函数对待。


任何在类内部定义的函数自动地为内联函数(in situ)。


在类中内联函数的最重要的用处之一是用于一种叫存取函数的函数。


不能作为内联处理的情况:

1函数太复杂,编译器将不能执行内联。

2显式或隐含地取函数地址,编译器也不能执行内联。(如果程序要取某个inline函数的地址,编译器通常必须为此函数生成一个outlined函数本体。编译器通常不对“通过函数指针而进行的调用”实施inlining

3构造和析构函数不应该内联,他们往往比看起来复杂。


一个较为合理的经验准则是, 不要内联超过 10 行的函数.谨慎对待析构函数,析构函数往往比其表面看起来要更长,因为有隐含的成员和基类析构函数被调用!

另一个实用的经验准则: 内联那些包含循环或 switch语句的函数常常是得不偿失 (除非在大多数情况下,这些循环或 switch 语句从不被执行).


        有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如虚函数和递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.虚函数内联的主要原因则是想把它的函数体放在类定义内, 为了图个方便, 抑或是当作文档描述其行为, 比如精短的存取函数.


我们几乎总是希望使用内联函数代替预处理器宏,然而当在标准C预处理器(通过继承也是C + +预处理器)里使用3个特别的特征时却是例外:字符串定义、字符串串联和标志粘贴。

#define DEBUG(X) cout<<#X<<"="<<X<<endl                           /*功能是输出变量的值,用在调试时*/
#define TRACE(S) cout<<#S<<endl,S     /*功能树输出执行的语句并执行,用于代码跟踪,#S代表原样输出, endl后面的S代表执行这一语句*/
#define FIELD(A) char * A##_string; int A##_size;     /*定义多个相似格式的变量,##表示连接为一个整体*/


“首先是使它起作用,然后优化它。”



原创粉丝点击