Effective C++ 条款40 明确而审慎地使用多重继承
1. 使用多重继承,派生类有可能从一个以上的基类继承相同名称,这回导致歧义.即使来自不同基类的相同名称各自的访问级别不同,也有仍然有可能造成歧义,因为C++的名称查找法则是先查找最佳匹配,然后再检查可取用性.可以使用作用域操作符明确指定所使用的名字属于那一个类.
2. 如果多重继承继承的一个以上基类又出现继承自同一个类的情况,将会导致"钻石型继承",即A->B;A->C;B,C->D,此时就要面对是否将A设为虚基类的选择.如果不采用虚继承,那么A在D中会存在两份实体(一份来自B,一份来自C),要使A在D中只有一份,那么B,C对A的继承应该采用虚继承,这又会招致额外成本,包括:1). 使用虚继承的类所产生的对象比不使用虚继承的大.2). 访问虚基类成员变量时,也比访问非虚基类慢. 3).支配"virtual base classes初始化"的规则比起non-virtual bases的情况复杂且不够直观,因为虚基类的初始化职责由继承层次的最底层负责,这意味着底层派生类初始化时必须时刻认知其虚基类,且必须承担虚基类初始化的责任.当一个新的派生类添加进时这种负担尤其明显.
3. 因此,非必要不使用多重继承,即使必须使用多重继承,也尽量避免使用虚基类,即使必须使用虚基类,也尽量避免在虚基类中放置数据成员以避免访问数据成员的额外时间代价以及初始化虚基类的负担.
4. 当然,多重继承也有其"正当用途":当一个类public继承自另一个类(is-a关系),而前者又需要借助第三个类来实现(is-implementation-in-terms-of关系),而采用private继承的时候,就需要public继承和private继承的两两组合.