首先说一下使用inline关键字的好处:
1、预处理(define)只是单纯的代码替换,使用inline可以解决define宏只是替换代码产生的问题,因为它像函数一样运作。
2、inline不需要承担函数调用的开销。本质上它也是代码展开。
inline关键字的坏处:
1、代码膨胀
inline void test()
{
std::cout<<"test"<<std::endl;
}
test();//将产生如下汇编代码
004012B1 mov eax,dword ptr [__imp_std::endl (403084h)]
004012B6 push eax
004012B7 push ecx
004012B8 mov ecx,dword ptr [__imp_std::cout (403080h)]
004012BE push offset string "test" (40318Ch)
004012C3 push ecx
004012C4 call std::operator<<<std::char_traits<char> > (401C30h)
004012C9 add esp,0Ch
004012CC mov ecx,eax
004012CE call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40303Ch)]
unsigned int i = splitA(p, ",", ve_str1, false);//一个非内联函数的汇编代码
004012F0 lea ecx,[esp+10h]
004012F4 mov byte ptr [esp+90h],4
004012FC call splitA (401120h)
可以看出,inline是通过空间来换时间的典型举措。
2、内联函数修改时,需要重新编译
这点很容易理解,内联函数只能在头文件中声明与定义。工程到一定规模的时候会浪费很多的时间在编译连接上。
3、无法调试内联函数
假如一个定义为内联的函数里面的断点生效了,那么它被编译器忽略了内联选项,一个非内联的内联函数。
使用内联函数的时候需要注意的:
1、要知道编译器为你生成的代码,比如一个看上去为空的构造函数其实包含了很多成员的构造过程,如果这部分展开的代码太长,编译器会忽略inline建议。大部分构造析构函数不建议为内联(在类的声明中定义即建议内联),因为他们太长了。
2、如果函数中包含静态变量,那么不建议声明为内联。
3、内联函数不能定义为虚拟的
virtual函数的调用是在运行期决定的,而内联函数是在编译期在被调用处进行代码替换。
4、一个内联函数是否真正内联是由编译器决定的
可以在函数中打断点,或者查看汇编来知道此函数是否被内联。
所以,谨慎地在确实能提高程序效率的%20部分正确地使用内联。
注:此篇为effective c++ 学习笔记,具体请看effective c++ item 33