Item32:确定你的public继承塑膜出is-a关系
Make sure public inheritance “is-a”.
Item33:避免遮掩继承而来的名称
Avoid hiding inherited names.
Derived中的同名非虚函数,将掩盖Base中的所有同名函数
using Base::func_name //引入Base中的函数实现部分覆盖
Base::func_name() //直接通过域作用符进行调用
Item34:区分接口继承和实现继承
Differentiate between inheritance of interface and inheritance of implementation.
①纯虚函数:只继承接口(也可以在类外定义),提醒用户必须在DC中具体实现。
②虚函数:继承接口和默认实现,又希望DC中覆写其实现。
③非虚函数:继承接口与实现,并且不允许覆写(否则覆盖其Base实现)
C++中的纯虚函数可以有实现,这样可以即提醒用户实现自己的函数,又可以让用户使用Base::func()完成默认实现
Item35:考虑virtual函数以外的其他选择
Consider alternatives to virtual functions.
①NVI(non-virtual interface)通过public non-virtual(virtual wrapper)间接调用virtual,从而可以实现一些额外的包装
②Strategy设计模式替换,通过传入各种函数对象进行实现
Item36:绝不重新定义继承而来的non-virtual函数
Never redefine an inherited non-virtual function.
Item37:绝不重新定义继承而来的缺省参数值
Never redefine a functions’s inherited default parameter value.
不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定的,可通过NVI将缺省参数放入public non-virtual函数的参数列表来控制这种问题。
Item38:通过复合塑膜出has-a或“根据某物实现出”
Model “has-a” or “is-implemented-in-terms-of” through composition.
composition:面向对象的一种实现方式,如set有一个红黑树,它是根据红黑树而实现。
Item39:明确而审慎的使用private继承
Use private inheritance judiciously.
- 仅需要重新定义继承而来的virtual函数或访问Base中的protected成员时合理,一般可用复合替换
- 编译器不会将DC自动转化为Base对象,毕竟两者成员访问不一致
class B{};
class D:private B
{
private n;
};
sizeof(B)!=0;
sizeof(int)==sizeof(D); //(EBO)空白基类最优化
Item40:明智而审慎的使用多重继承
Use multiple inheritance judiciously.
virtual继承会增加大小,速度,初始化(赋值)复杂度等成本,如果virtual base class不带任何数据,将是最具实用价值的情况。