
讯享网点蓝色字关注“CurryCoder”
微信公众号:CurryCoder的程序人生
怕什么真理无穷,进一寸有一寸的欢喜

1.inline函数的爱恨两难

2.inline函数卑微在线求助
inline只是对编译器的一个申请建议,不是强制命令,编译器可以选择对你的建议置之不理 。 这项申请可以隐式声明也可以显式声明,隐式声明是将函数定义在类的内部,如下所示:class Person{
public:
// ...
int age() const {
return mAge;} // 隐式的内联函数
private:
int mAge;
};
讯享网 显式声明的方法则是在函数定义式前面加上关键字inline,如下面函数模板:
讯享网template<typename T>
inline const T& max(const T& a, const T& b){
return a }
上述显式的声明方法中 ,
值得注意的一点是:inline函数和函数模板通常都被定义于头文件中。但是,函数模板未必一定是内联的!!!inline函数通常一定被放置在头文件中,因为大多数构建环境在编译过程中进行内联动作,为了将一个函数调用替换为被调用函数的本体,编译器必须知道那个函数是啥样。
内联动作在大多数C++程序中是编译期的行为。 函数模板通常也被放置在头文件中,因为它一旦被使用,编译器为了将它具体化,需要知道它的样子。某些构建环境中,可以在连接期执行模板具体化,只不过编译期完成具体化的动作比较常见。
3.inline函数与虚函数的爱恨纠缠
大部分编译器拒绝将太复杂(带有循环或递归、switch-case语句)的函数设置为inline,而且所有对虚函数的调用也都会使inline失效。这是因为虚函数是直到运行期才会确定调用哪个函数,而inline函数意味着执行前先把调用动作替换为被调用函数的本体,编译器工作在编译期。如果编译器都不知道该调用哪个函数,你也就明白了为啥虚函数不建议设置为inline。更多详情原因请看这里https://www.jianshu.com/p/84add
4.糟糕的内联选择:构造函数与析构函数不要被你的眼睛所欺骗,下面子类构造函数真的是空的吗???
class Base{
public:
// ...
private:
string bm1, bm2;
};
class Derived: public Base{
public:
Derived(){} // Derived构造函数真的是空的吗???
// ...
private:
string dm1, dm2, dm3;
};
当你使用new,动态创建的对象被其构造函数自动初始化;当你使用delete,对应的析构函数会被调用。当你创建一个对象时,基类及其每个成员变量都会被自动构造;当你销毁一个对象时,从子类开始执行析构动作。
如果有个异常在对象构造期间抛出,该对象已构造好的那一部分会被自动销毁 。你的程序内一定有某些代码让那些事情发生,这些代码即编译器在编译期间产生并安排在你代码中的某个地方。有时候,可能就存在于你的构造函数和析构函数中。上面表面上看起来空的Derived构造函数所产生的代码,如下所示:
讯享网Derived::Derived(){
Base::Base();
try{
dm1.string();
}
catch(...){
Base::~Base();
throw;
}
try{
dm2.string();
}
catch(...){
dm1.string();
Base::~Base();
throw;
}
try{
dm3.string();
}
catch(...){
dm2.string();
dm1.string();
Base::~Base();
throw;
}
}
上面的代码并不能代表编译器真正产生的代码,因为真正的编译器会以更复杂的做法来处理异常。尽管如此,上面的代码已经能反映Derived的空白构造函数必须提供的行为。不论编译器在其内部所做的异常处理有多么复杂,Derived构造函数至少一定会陆续调用成员变量和基类两者的构造函数,而那些调用会影响编译器是否对此空白函数执行内联动作。 最后,程序库的设计者必须知道:内联函数无法随着程序库的升级而升级。如果fun()是程序库中的一个内联函数,客户将fun()本体编进其程序中,一旦程序库设计者决定改变fun(),所有用到函数f()的客户端程序都必须重新编译。如果fun()是non-inline函数,一旦它有所修改客户端只需要重新连接即可。
对程序开发而言,大部分调试器对内联函数都束手无策 ,因为你无法在一个并不存在的函数内部设置断点进行调试呢?哪些函数可以设置为inline呢?我的建议是:首先不要将任何函数声明为inline,或者将inline实施范围局限在那些一定可以成为inline的场合。
5.总结 (1) 将大多数inline行为限制在小型、被频繁调用的函数身上。这可以使以后的调试过程和二进制升级更容易,也可以使潜在的代码膨胀问题最小化。 (2) 不要只是因为函数模板出现在头文件中,就将它们声明为inline。
觉得不错,请一键三连吧↓↓↓
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/35745.html