确定你的public继承塑模出is-a关系。student is a person,所以student可以public继承自person。概念上,正方形是长方形,但是如果让square继承自rectangle呢,square需要像rectangle那样具有长和宽两个成员变量吗?如果是,每次改变正方形的宽的时候,也要改变正方形的长,这很奇怪不是吗?所以is-a关系不仅仅是现实概念上的,也是实现上的,确保对于base class对象身上发生的每件事对derived class对象而言是自然的,因为public意味着is-a关系。
避免遮掩继承而来的名称。public继承时,如果derived class内有与base class同名的函数,是同名,不管是否virtual、参数类型、常量性,那么derived class中的函数都会屏蔽掉base class中的那些(不是一个,而是所有)函数,原因是编译器解析函数名称时的查找规则。屏蔽base class中的函数往往不是我们想要的,因为derived class object is-a base class object。解决方案是在derived class声明中加上语句using::member_function_name;只是member_function_name没有其他。
通过复合塑模出has-a语义或”根据某物实现出“语义。A拥有B,那就使用复合,A的一些操作需要B的一些操作完成,但是B is not a A,也可以使用复合,尽量避免不要使用继承,这会为类设计带来低内聚和紧耦合的问题。复合的形式可以是A类中含有一个B类成员,也可以是A类中某个成员函数使用了B类对象作为参数。
明智而审慎地使用多重继承。多重继承有用,但是多重继承往往比单一继承复杂,并且容易导致歧义产生概率的增高(还记得钻石型结构吗?),virtual继承是解决歧义的一种方法,但是却不得不为此付出空间、效率、初始化复杂度的代价,对于virtual base class尽量不用,如果用了,也不要再其中放置数据成员。多重继承的一个应用场景是“public继承自某个interface class”与“private继承自某个协助实现的class”的两相组合。