14-3多重继承
多重继承
MI描述的是有多个直接基类的类。这同样描述的是is-a关系的继承关系。
公有MI有以下两个问题:
1.从两个基类继承了两个同名方法
2.从两个或更多基类中继承了同一个类的多个实例
14.3.1虚基类–解决基类问题
虚基类使从多个基类相同的类中派生出的对象只继承一个基类对象。
使用
在类声明中使用关键字virtual。
class Singer : virtual public Worker{...}; |
这个SingingWaiter只有Worker对象的一个副本
新的函数构造规则
对于使用虚基类,第三代构造函数如果在初始化列表中调用第二代派生类构造函数,则会通过两条不同的途径将数据传递给虚基类对象。因此C++在基类是虚的时候禁止这种传参方式,而是采用直接显式地在初始化列表中调用虚基类的构造函数。
SingingWaiter(const Worker & wk, int p = 0, int v = Singer::other) : Worker(wk), Waiter(wk,p), Singer(wk,v){} |
此处使用Worker(wk)来初始化虚基类对象
注:对于虚基类,这种方式是合法的,对于非虚基类,这种方式是非法的。
14.3.2方法冲突–解决方法问题
除了修改构造函数,MI还需调整方法。
对于单继承,如果调用方法,则会使用继承的类中的方法,但对于MI来说,如果继承的两个类出现同名方法,不能确定使用哪一个方法,从而产生二义性。
解决方案
1.在成员名字前面加上类名和域解析符::
,以显式地指明到底使用哪个类的成员,消除二义性
SingingWaiter newhere("Elise Hawks", 2005, 6, soprano); |
2.使用模块化方法重新组装函数
在基类和派生类中只给出自己成员的处理函数,再在三代派生中组装函数
案例
void Worker::Data() //基类 |
3.将所有的数据组件设置为保护的而非私有的
总结案例
该案例总结地使用了上述方法
//workermi.h |
//workermi.cpp |
其它问题
1.混合使用虚基类和非虚基类
当基类是虚基类时,派生类包含基类的一个子对象;当基类不是虚基类时,派生类包含多个子对象。
当混合使用时,虚基类共享一个对象,非虚基类对象数目递增。
2.虚基类和支配
在不使用虚基类的情况下,如果使用不同基类继承的同名成员,可能导致二义性。
但使用虚基类,如果在某个名称优先于其它名称的情况下,先使用这个名称。
派生类中的名称优于直接或间接祖先类中的相同名称
发布于