Effective C++ 读书笔记(35-44):继承关系与面向对象设计

Item35 -- 确定你的public继承,模拟出is-a关系

public继承是is-a关系,潜在含义就是基类的所有函数在子类中都能用。举个范例,所有鸟都会飞,但是鸭子不会,所以鸭子不能从鸟public继承而来。如果一定要用,也要讲鸟划分成会飞的鸟和不会飞的鸟,鸭子从不会飞的鸟公开继承。

Item36 -- 区分接口继承和实现继承

  1. 声明一个纯虚函数的目的是让子类只继承其接口
  2. 声明一般(非纯)虚函数的目的,是为了让子类继承该函数的接口和缺省行为
  3. 声明非虚函数的目的是为了让子类继承函数的接口和实现。且"不变性"凌驾于"变异性"之上,我们不应该在子类重新定义它。

以上三点都是在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 -- 明智地运用私有继承

  1. 如果是私有继承,编译器不会隐式的将子类对象转化成基类对象
  2. 私有继承,基类所有函数在子类都变成私有属性
  3. 私有继承意味着根据某物实现,与layering相比,当protected members和虚拟函数牵扯进来会有很大的优越性。
  4. 私有继承,子类仅仅是使用了父类中的代码,他们没有任何概念上的关系。

Item43 -- 明智地运用多继承(MI)

  1. 多继承会产生模棱两可,子类调用方法如何两个父类都有,则必须指明使用的是哪个父类
  2. 多继承会产生钻石型继承体现,为了使得祖先类只有一份,请在两个父类继承祖先的时候采用虚继承(而这在设计祖先类的时候一般是无法预料到的)
  3. 可以通过public继承方式继承接口,private继承方式继承实现,来完成目的

Item44 -- 说出你的意思,并了解你所说的每一句话

条款44其实是上面所有的总结

你可能感兴趣的:(effective)