25.4 继承的原则
a)继承是为了扩展性,组合是为了代码重用
b)尽量使用纯虚类,既其中无属性,仅仅提供接口等
c)多继承的替代方式:the "bridge" pattern or nested generalization
25.5诠释以上三大原则
三种方式各有优缺点:
桥模式:共有n+m个子类,增加了代码的重用,但是如果
1.n×m的组合方式算法各不相同,则维护工作量巨大
2.不能随意组合,例如例子中的脚踩的太空飞船,需要增加额外检查
3. users cannot pass any gas powered vehicle as a GasPoweredVehicle,没有比较好的类层次结构
多层次嵌套继承:
1.可以有多种算法
2.任意增加一种类层次,相应的需要扩展很多类,但是限制了不合理类的使用,例如脚踏太空飞船
3.同样存在以上3中的缺点
多继承:
1.得写n*m个子类
2.namely it allows a user to pass any gas powered vehicle using a common base class,此为前两种无法做到的
3.代码可像桥模式一样重用,也可覆盖
25.6简图
Grow Gracefully? | Low Code Bulk? | Fine Grained Control? | Static Detect Bad Combos? | Polymorphic on Both Sides? | Share Common Code? | |
Bridge | ![]() | ![]() (N+M chunks) | no | no | no | ![]() |
Nested generalization | no | no (N*M chunks) | ![]() | ![]() | no | no |
Multiple inheritance | no | no (N*M chunks) | ![]() | ![]() | ![]() | ![]() |
25.7 多继承的原则
此处列举的例子倾向多继承
水上飞机,陆上飞机,两栖飞机
1.我们是否需要添加新的完全不同的类,针对两栖分级
2.两栖飞机是否可以用水上飞机或陆上飞机引用,调用这些父类方法是否可以实际调用到两栖飞机的实现
25.8 dread-diamond
Base
/ \
/ \
/ \
Der1 Der2
\ /
\ /
\ /
Join
此种方式下JOIN中的成员变量将有两套Base,实际使用过程中有时需要加前缀避免歧义
25.9 如何解决dread-diamond
Der1和Der2均虚继承Base.
Base / \ / \ virtual / \ virtual Der1 Der2 \ / \ / \ / Join代码显示为:
class Der1 : public virtual Base {
public: ^^^^^^^—this is the key
...
};
[25.10] What does it mean to "delegate to a sister class" via virtual inheritance?
此处不容易解释清楚,建议查看英文版原文
个人理解算是环状继承的一个副作用吧。
简单的说就是Base定义了多态方法,der1和der2分别实现了互不交集的方法,当用JOIN实例化对象后,两个父类中的方法互相可以访问到对方
25.14多继承初始化的顺序
首先所有的virtual base class constructors ,然后非virtual类,同时也是依次序从父到子递归执行初始化