C++ 语言的函数内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作类的数据成员。所以在C++ 程序中,应该用内联函数取代所有宏代码.
1.宏定义只是简单的文本替换,不做任何安全性的检查也不像函数那样在栈上创建新的变量空间.
(1)宏定义可能会造成cxy不希望的变量多次累加;在下面F宏定义中基本上是x出现了几次就会被累加了几次.
#define F(x) x+x #define F3(x) x+x+x int i = 0; cout<<F(i++)<<endl;//1 <=> (i++ + i ++) i is added twice cout<<i<<endl;//2 int j = 0; cout<<F3(j++)<<endl; //3 cout<<j<<endl; //3
(2)没有类型检查,可能传进来任意类型.
#define MAX(a,b) ((a)>(b)?(a):(b)) MAX(a,"Hello"); //错误地比较int和字符串,没有参数类型检查
2.宏定义无法操作类的私有成员,而inline函数可以.
综上,C++ 语言的函数内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作类的数据成员。所以在C++ 程序中,应该用内联函数取代所有宏代码.
BUT , “断言assert”恐怕是唯一的例外。assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生 的情况。为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。如果assert是函数,由于函数调用会引起内 存、代码的变动,那么将导致Debug版本与Release版本存在差异。所以assert不是函数,而是宏。
1.inline用于实现的关键字并不是生成类型关键字.比如如下定义并不起作用:
inline void foo();// inline仅与函数声明放在一起 void foo() { }
而如下风格的函数Foo则成为内联函数:
void Foo(int x, int y); inline void Foo(int x, int y) // inline与函数定义体放在一起 { … }
2.定义在类声明之中的成员函数将自动地成为内联函数(类声明与实现分离与否的重要区别),例如
class A { public: void Foo(int x, int y) { … } // 自动地成为内联函数 }
内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率 的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。所以不要随便地将构造函数和析构函数的定义体放在类声明中。
一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了inline不应该出现在函数的声明中)。
原文:http://www.cnblogs.com/luntai/p/6251727.html