存在基类Worker,其中包含名字信息name(string)以及编号信息id(int),现有Singer和Waiter类均继承于Woker类,即 class Singer:public Worker{.....} ;和 class Waiter:public Worker{.......};。假设再由Singer和Waiter派生出SingingWaiter类即class SingingWaiter:public Singer,public Waiter{.....};
因为Singer和Waiter均继承于Worker,因此在SingingWaiter中包含两个Wokrer组件,这将引起问题。例如通常可以将派生类的地址赋值给基类指针,但现在将出现二义性,
SingingWaiter ed; Worker* pw = &ed ; ,因为在ed中有两个Worker对象,有两个地址可供选择。一般可以采用强制类型转换来选择所需对象,即 Worker* pw = (Singer*) &ed; 和 Worker* pw = (Waiter*) &ed; ,但采用这种方式编程会十分的繁琐,因此引入了一种新技术——虚基类。
虚基类
虚基类使得从多个类(它们的基类相同)派生出的对象只继承一个基类对象。声明方式如下所示:class Waiter:virtual public Worker{.......}; class Singer:virtual public Worker{.........};同理SingingWaiter被定义为class SingingWaiter:public Singer,public Waiter{.....};从本质上讲继承的Singer和Waiter对象共享同一个Worker对象,而不是各自引入自己的Worker副本
新的构造函数规则
如果Worker是虚基类,则这种信息传递将不起作用。例如,对于下面的MI构造函数SingingWaiter(const Worker& wk,int p = 0,int v = Singer::other):Waiter(wk,p),Singer(wk,v){},该构造函数存在的问题是,自动信息传递时,将通过两条不同的方式(Singer和Waiter)将wk传递给Worker对象。为了阻止这种传递,C++在基类是虚类的时候,禁止信息从中间类传递到基类。因此,上述构造函数初始化panache和voice,但wk中的信息不会传递给Worker。
实际的构造函数应该是这样的:
SingingWaiter(const Worker& wk,int p = 0,int v = Singer::other):Worker(wk),Waiter(wk,p),Singer(wk,v){},