条款30:透彻了解inlining的里里外外

来源:互联网 发布:百度云会员激活码淘宝 编辑:程序博客网 时间:2024/05/01 02:01
首先,inline函数只是一个申请,而不是命令。编译器可以执行你的申请,也可以拒绝。
申请有两种形式:隐式申请:在类内部定义的函数都默认为inline函数,甚至包括内部定义的友元函数。显示申请:使用inline关键字。
其次,inline函数一般要放到头文件中,因为编译器需要在程序调用内联函数时立刻将他替换,所以必须要知道这个函数的具体内容。类似的还有模板,必须在让编译器能够在调用模板的的程序所在的源文件中看到模板,然后才能对它实例化。有一点需要注意,如果你把一个函数模板定义为内联的,那么这个模板的所有实例都是内联的。如果没有必要让这个函数模板的所有实现都是内联的,那么就不要把它声明为内联。
大部分编译器,对于过于复杂的inline函数,都会忽略这个申请,比如带有循环或者递归的函数,以及虚函数,虚函数要求在程序执行到时才判断到底使用的是哪个函数,而内联函数意味着在程序执行前就将函数替换为被调用函数的内容。

有些时候,即使编译器希望使用内联函数,但还是会产生一个函数的本体,比如:使用某个内联函数的地址(指向函数的指针):

inline int min(const int& a, const int& b){return a>b?a:b;}int (*pf)(const int&,const int&) = min;cout<<pf(3,4)<<endl;cout<<min(3,4)<<endl;

那么此时并不会使用内联,而是调用一份函数的副本。
很多时候,我们都倾向于把类的构造函数,析构函数设为内联函数,但这并不是一个好注意。因为很多看似简短的构造函数身后,隐藏着编译器为你默默填写的大量的函数,尤其是在继承派生体系中。
如果把一个函数声明为inline,那么如果修改了他,所有调用它的函数程序都得重新编译,而如果它只是一个普通函数,那么只需要重新链接就可以了。
所以,我们应该一开始先不要声明任何函数为inline,而是以后随着程序的逐步深入,才考虑哪些函数声明为inline

原创粉丝点击