宏代码与内联函数区别(转)
上一篇 /
下一篇 2012-07-18 21:58:19
/ 个人分类:C\C++
语言支持关系:
C 宏代码
C++ 宏代码 内联函数
宏代码本身不是函数,但使用起来象函数.预处理器用复制宏代码的方式代替函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return 等过程,从而提高了速度.使用宏代码最大的缺点是容易出错,预处理器在复制宏代码时常常产生意想不到的边际效应.
对于任何内联函数,编译器在符号表里放入函数的声明(包括名字、参数类型、返回值类型).如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里.在调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样).如果正确,内联函数的代码就会直接替换函数调用,于是省去了函数调用的开销.这个过程与预处理有显著的不同,因为预处理器不能进行类型安全检查,或者进行自动类型转换.假如内联函数是成员函数,对象的地址(this)会被放在合适的地方,这也是预处理器办不到的.
宏定义是预处理器在代码优化时直接替换的,而内联函数是在编译期间插入代码.宏定义替换比内联函数执行得早
内联函数使用方法:
关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用.
正确使用方法:
void Foo(int x, int y);
inline void Foo(int x, int y) // inline 与函数定义体放在一起
{
…
}
错误使用方法:
inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y)
{
…
}
.在内联函数内不允许用循环语句和开关语句。
如果内联函数有这些语句,则编译将该函数视同普通函数那样产生函数调用代码,递归函数(自己调用自己的函数)是不能被用来做内联函数的。内联函数只适合于只有1~5行的小函数。对一个含有许多语句的大函数,函数调用和返回的开销相对来说微不足道,所以也没有必要用内联函数实现。
2.显式内联函数和隐式内联函数
a.在类声明的内部声明,而在类声明外部定义叫做显式内联函数,如:
class display
{
int t;
public:
void output(void)
}
display object;
inline void display::output(void)
{
cout << "i is " << i <<"\n";
}
b.在类声明的内部定义,叫做隐式内联函数,如:
class display
{
int t;
public:
inline void output(void)
{cout<<"i is "<< i << "\n";}
}
慎用内联
内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?
如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?
内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。所以不要随便地将构造函数和析构函数的定义体放在类声明中。
一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了inline不应该出现在函数的声明中)。
收藏
举报
TAG: