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继承的两两组合.

时间: 2024-08-10 18:00:04

Effective C++ 条款40 明确而审慎地使用多重继承的相关文章

Effective C++ Item 40 明智而审慎地使用多重继承

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:多重继承比单一继承复杂.它可能导致新的歧义性,以及对 virtual 继承的须要 演示样例: class BorrowableItem{ public: void checkOut(); }; class ElectronicGadget{ private: bool checkOut() const; }; class MP3Player: public BorrowableIte

Effective C++ -----条款40:明智而审慎地使用多重继承

多重继承比单一继承复杂.它可能导致新的歧义性,以及对virtual继承的需要. virtual继承会增加大小.速度.初始化(及赋值)复杂度等等成本.如果virtual base classes不带任何数据,将是最具实用价值的情况. 多重继承的确有正当用途.其中一个情节涉及“public继承某个Interface class"和”private继承某个协助实现的class“的两相组合.

Effective C++ 条款39 明智而审慎地使用private继承

1. public继承表明is-a的关系,要求接口的完全继承,而private继承表明"根据某物实现出的关系",要求仅仅继承实现,private继承有两个规则: 1). 经由private继承而来的基类的所有成员在派生类中都会变成private属性 2). 由于1),编译器不允许将派生类转为基类以防止对派生类private成员的非法访问. 2. 由条款38,private继承和复合具有相同作用——"根据某物实现出".两者之间,要尽可能使用复合,除非必要情况.必要情况

Effective C++条款40

本节条款讲述了多重继承的使用 多重继承一般情况下用的很少,原因在于多重继承容易出现程序错误.以下去两个典型的调用错误: 第一种错误如下代码: #include<iostream> using namespace std; class B { public: virtual int m(){} }; class C { public: virtual int m(){}; }; class D :public B,private C { public: }; int main() { D d;

Effective C++:条款40:明智而审慎地使用多重继承

(一) 慎用多重继承,因为那样的话可能会造成歧义.. <pre name="code" class="cpp">class BorrowableItem { public: void checkOut(); }; class ElectronicGadet { private: bool checkOut() const; }; class MP3Player : public BorrowableItem <pre name="code

effective c++条款32~40“继承与面向对象设计”整理

条款32:确定你的public继承塑模出is-a关系 以C++进行面向对象编程,最重要的一个规则是:public inheritance(公有继承)意味is-a(是一种)的关系. 在C++领域中,任何函数如果期望获得一个类型为基类的实参(而不管是传指针或是引用),都也愿意接受一个派生类对象(而不管是传指针或是引用).(只对public继承才成立.)好的接口可以防止无效的代码通过编译,因此你应该宁可采取"在编译期拒绝"的设计,而不是"运行期才侦测"的设计.is a并不

Effective C++ Item 39 明智而审慎地使用 private 继承

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:private 继承意味 is-implemented-in-terms of.它通常比 composition 的级别低. 但是当 derived class 需要访问 protected base class 的成员,或需要重新定义继承而来的 virtual 函数时,这么设计是合理的 经验:和 composition 不同, private 继承可以造成 empty base 最

More Effective C++ 条款35 让自己习惯于标准C++ 语言

(由于本书出版于1996年,因此当时的新特性现在来说可能已经习以为常,但现在重新了解反而会起到了解C++变迁的作用) 1. 1990年后C++的重要改变 1). 增加了新的语言特性:RTTI,namespaces,bool,关键词mutable和explicit,enums作为重载函数之自变量所引发的类型晋升转换,以及"在class 定义区内直接为整数型(intergral) const static class members设定初值"的能力. 2). 扩充了Templates的特性

effective c++ 条款4 make sure that objects are initialized before they are used

1 c++ 类的数据成员的初始化发生在构造函数前 class InitialData { public: int data1; int data2; InitialData(int a, int b) { data1 = a: //this is assignment data2 = b; //this is assignment } /* InitialData(int a, int b):data1(a),data2(b) //this is initial {} */ } 2 不同cpp文