Item35 -- 确定你的public继承,模拟出is-a关系
public继承是is-a关系,潜在含义就是基类的所有函数在子类中都能用。举个范例,所有鸟都会飞,但是鸭子不会,所以鸭子不能从鸟public继承而来。如果一定要用,也要讲鸟划分成会飞的鸟和不会飞的鸟,鸭子从不会飞的鸟公开继承。
Item36 -- 区分接口继承和实现继承
- 声明一个纯虚函数的目的是让子类只继承其接口
- 声明一般(非纯)虚函数的目的,是为了让子类继承该函数的接口和缺省行为
- 声明非虚函数的目的是为了让子类继承函数的接口和实现。且"不变性"凌驾于"变异性"之上,我们不应该在子类重新定义它。
以上三点都是在public继承的条件下成立。
Item37 -- 绝对不要重新定义继承而来的非虚拟函数
同条款36的第三点,不变性凌驾于变异性之上
Item38 -- 绝对不要重新定义继承而来的缺省参数值
缺省参数是静态性别,及时采用虚函数进行多态,但是缺省参数是不变的,因此重新定义继承而来的缺省参数会导致混淆。
Item39 -- 避免在继承体系中做向下转型动作
向下转型必然导致if then else,而这个可以用虚函数来实现。同样,当使用过多的switch的时候,也可以考虑利用虚函数进行优雅的实现。回想一个问题,小机器人,根据ewsn四个指令向东向西向南向北走,采用虚函数进行实现。
Item40 -- 通过layering技术来塑造has-a或is-implemented-in-terms-of
layering又称组合,内含另一类的对象,通过包裹该对象的行为来实现自己的接口。但是这种情况会产生编译依赖的问题,可以参考条款34.
Item41 -- 区分继承和模板
模板用来产生一群class,其中对象性别不会影响class的函数行为
继承应用于一群class身上,其中对象性别会影响class的函数行为
Item42 -- 明智地运用私有继承
- 如果是私有继承,编译器不会隐式的将子类对象转化成基类对象
- 私有继承,基类所有函数在子类都变成私有属性
- 私有继承意味着根据某物实现,与layering相比,当protected members和虚拟函数牵扯进来会有很大的优越性。
- 私有继承,子类仅仅是使用了父类中的代码,他们没有任何概念上的关系。
Item43 -- 明智地运用多继承(MI)
- 多继承会产生模棱两可,子类调用方法如何两个父类都有,则必须指明使用的是哪个父类
- 多继承会产生钻石型继承体现,为了使得祖先类只有一份,请在两个父类继承祖先的时候采用虚继承(而这在设计祖先类的时候一般是无法预料到的)
- 可以通过public继承方式继承接口,private继承方式继承实现,来完成目的
Item44 -- 说出你的意思,并了解你所说的每一句话
条款44其实是上面所有的总结