@cxm-2016
2016-09-08T14:40:21.000000Z
字数 1151
阅读 1900
c++
no
假如B和C都继承自A而D继承自B和C,那么D对象中包含几个A对象呢?[1]
虚基类使得从多个类派生出的对象只继承一个基类对象:
class Singer : virtual public Worker{...};
class Waiter : public virtual Worker{...};
然后可以将SingingWriter定义为:
class SingingWriter : public Singer , public Waiter {...};
现在SingingWriter只包含一个Worker副本。
使用虚基类时,需要对类构造函数采用一种新的方法。对于非需基类,我们只需要调用声明的基类的构造方法,不需要关心基类的基类的构造方法是什么样的:
class A{
public:
A(int a){}
};
class B : A{
public:
B(int a,int b):A(a){}
};
class C : B{
public:
C(int a,int b,int c):B(a,b){}
};
但是对于虚基类,我们就不能再采取这样的方式,而应该采用下面的方式
SingingWaiter(const Worker & wk,int p,int v):
Worker(wk),Waiter(wk,p),Singer(wk,v){}
也是就说,需要显式的调用被声明为虚基类的构造方法。
对于单继承,方法调用会查找继承链中最近的重写方法。而在多继承系统中,每一个直接祖先都已共同基类中的方法。我们有如下几种方式解决二义性:
SingingWaiter sw;
...
sw.Singer::show();
对于使用作用域解析符的方法甚是繁杂。所以我们可以在子类中声明并定义一个自己的方法
void SingingWaiter::show(){
Singer::show();
}
最后一种方式是将所有的数据组件都设置为保护的,而不是私有的,收方法的保护,外界不可以直接访问基类的方法,也就间接的防治了二义性的发生。
假设A是B和C的虚基类,并作为D和E的非需基类,F类继承了B、C、D、E四个类。F对象中将会包含几个A对象。由于B、C是以虚基类方式继承了A所以这里只会产生一个A对象,但是对于D和E没有声明虚基类,就导致每个基类都会携带一个A对象。所以一共产生了3个A对象。