在https://blog.youkuaiyun.com/Master_Cui/article/details/106391552中,已经简单的说过内联函数的作用。
函数体较小的内联函数经过编译后,可以生成较小的目标码,但是如果内联函数的函数提很大,那么目标码就会很大,运行起来后,占用的内存就会很多,有可能发生换页并降低缓存命中率,导致程序运行效率变慢。所以,内联函数的函数体不能太大(不要超过10行)。只要内联的函数体较小,内联该函数可以令目标代码更加高效。对于存取函数以及其它函数体比较短,性能关键的函数,鼓励使用内联。
如果一个函数模板所有的实例都应该是内联的,可以将此函数模板声明为inline;否则就应该不要将这个函数声明为inline(不论显式或隐式)。
构造函数和析构函数也不要声明为内联,因为在继承体系中,因为构造函数和析构函数中有隐含成员的创建和销毁,以及基类构造函数和析构函数的调用,所以,构造函数和析构函数往往比表面看起来更长。像下图这样

因为在类内实现的函数默认是内联函数,所以,不要在类内实现构造函数和析构函数。
除了构造析构和超过10行的函数外,也不要将包含循环或switch语句的函数声明为内联函数。
此外,即使将函数声明为inline,在编译时,也不一定会被编译器展开;比如虚函数的调用是在运行期确定的,而内联函数的展开是在编译期进行。虚函数内联的主要原因是基类虚函数的函数体经常为了方便放在类内定义。递归函数即使是inline的也不会被展开,编译器对于递归的内联函数会拒绝内联展开
如果通过内联函数的指针调用内联函数,编译器一般也不会在调用点展开,因为,编译器通常必须为此函数指针指向的函数生成一个函数本体。

这也就是为啥在使用函数对象进行传参时,多使用函数调用运算符,少使用函数指针,见https://blog.youkuaiyun.com/Master_Cui/article/details/112553067
十八、如何降低编译成本

上述代码中的person类存在以下问题:
2、Person类和自定义头文件之间形成了编译依赖。任意一个头文件被改变,或这些头文件所依赖的其他头文件有改变,那么每一个含有或使用Person类的文件就得重新编译,连串的编译依赖会导致大量文件被重新编译,增加编译的时间
2、将person封装成一个抽象类,将具体的实现放在子类中,然后用抽象类的指针指向该子类
处理继承体系中同名不同参的成员函数除了在https://blog.youkuaiyun.com/Master_Cui/article/details/109849186中提过的指定作用域的方法
class base
{
public:
base(){cout<<__func__<<endl;}
~base(){cout<<__func__<<endl;}
void func(int init) {cout<<__func__<<"in base"<<endl;}
};
class derive:public base
{
public:
derive(){cout<<__func__<<endl;}
~derive(){cout<<__func__<<endl;}
using base::func;//新添加的using声明式
void func() {
cout<<__func__<<"in derive"<<endl;
}
};
int main(int argc, char const *argv[])
{
derive d;
base *pb=&d;
pb->func(10);
d.func(10);
return 0;
}
在第14行添加新的using声明式之后,编译器发现子类中的函数参数不匹配时,会调用基类中的func,避免了名称遮掩问题
二十、私有虚函数
子类继承基类后,将基类中的虚函数重新实现,即使该虚函数的访问权限为private,用户也可以通过多态绕过private
示例
class base
{
public:
base(){}
virtual ~base(){}
virtual void func() {cout<<"func in base"<<endl;}
};
class derive:public base
{
public:
derive(){}
~derive(){}
private:
void func() {cout<<"func in derive"<<endl;}
};
int main(int argc, char const *argv[])
{
base *bp=new derive();
bp->func();
return 0;
}

所以,最好不要把虚函数设置为private。
参考
《Effective C++》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出
本文探讨了C++中的内联函数使用策略,包括其对代码效率的影响,以及何时不应声明为内联。同时,介绍了降低编译成本的方法,如减少编译依赖和封装数据成员。还讨论了处理继承体系中同名不同参函数的两种方式,以及私有虚函数可能导致的多态安全性问题。最后,提醒开发者注意不要将虚函数声明为private。
3135

被折叠的 条评论
为什么被折叠?



