32、确定你的public继承塑模出is-a关系
(1)public 继承意味着is-a。适用于base class身上的每一件事一定也适用于derived class身上,因为每一个derived class对象也就是一个base class 对象。
33、避免遮掩继承而来的名称
(1)derived class内的名称会掩盖base class内的名称,不论函数是否是virtual或者参数是否一致。
(2)为了让被遮掩的名称再见天日,可使用using 声明式或者转交函数,转交函数时base class名称加::函数名,并且暗自为inline。
34、区分接口继承和实现继承
(1)接口继承和实现继承不同。在public继承之下,derived class总是继承base class的接口。
(2)声明一个pure virtual函数的目的是为了让derived class只继承函数接口;而impure virtual函数的目的是让derived class继承该函数的接口和缺省实现;声明non-virtual函数的目的是为了令derived class继承函数的接口以及一份强制性实现。
35、考虑virtual函数以外的其他选择
(1)使用NVI(non-virtual interface)手法,那是Template Method设计模式的一种特殊形式。它以public non-virtual成员函数包裹教低访问性(private或protected)的virtual函数。优点是确保在virtual函数进行真正工作之前和之后可以设定好场景和清理场景。
(2)将virtual函数替换为“函数指针成员变量”,这是strategy设计模式的一种分解表现形式。优点是像是“每个对象可各自拥有自己的函数”和“可在运行期改变计算函数”,带来的缺点是,非成员函数无法访问class的non-public成员,需要声明为friend。
(3)以tr1::function成员变量替换virtual函数,因而允许使用任何调用物搭配一个兼容于需求的签名式。这也是strategy设计模式的某种成分。
(4)将继承体系内的virtual函数替换为另一个继承体系内的virtual函数。这是strategy设计模式的传统实现手法。
36、绝不重新定义继承而来的non-virtual函数
37、绝不重新定义继承而来的缺省参数值
(1)virtual函数系动态绑定,而缺省参数值却是静态绑定,c++这样做是出于效率的考虑。所谓静态类型,是它在程序中被声明时所采用的类型;动态类型是指目前所指对象的类型。
38、通过复合塑模出has-a或“根据某物实现出”
(1)在应用域,复合意味着has-a;在实现域,复合意味着is-implemented-in-terms-of(根据某物实现出)。
39、明智而审慎地使用private继承
(1)private继承纯粹是一种实现技术,只是意味着只有部分被继承,接口部分没有继承。
(2)empty class对象不使用任何空间,因为没有任何隶属对象的数据需要存储。但是,C++裁定凡是独立对象必须有非零大小。EBO(empty base optimization,空白基类最优化),stl中的base class unary_function和binary_function都是empty class,这样的继承很少增加derived class的大小。Private继承可以造成empty base最优化,这对“对象尺寸最小化”的开发者很重要。
(3)private 继承意味着is-implementated-in-terms of。它通常比复合级别低,但是当derived class需要访问protected base class的成员,或者需要重新定义继承而来的virtual函数时,这么设计是合理的。
40、明智而审慎地使用多重继承
(1)多重继承比单一继承复杂,可以会导致歧义(如两个基类中都有一个函数,调用时必须要明确是哪个基类中的函数),以及对virtual继承的需要(如“钻石型多重继承”,此时令带有数据的base class成为virtual base class)。
(2)virtual继承为增加大小、速度、初始化(及赋值)复杂度等等成本。如果virtual base class不带任何数据,将是最具有实用价值的情况。
(3)多重继承的确有正当用途。其中一个情节涉及“public 继承某个interface class”和“private继承某个协助实现的class”的两相组合。