C++:虚基类

C++:虚基类

标签(空格分隔): c++


假如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){}

也是就说,需要显式的调用被声明为虚基类的构造方法。

方法的二义性


对于单继承,方法调用会查找继承链中最近的重写方法。而在多继承系统中,每一个直接祖先都已共同基类中的方法。我们有如下几种方式解决二义性:

  • 使用作用域解析符
  • 在子类重定义方法
  • 设置保护性继承

1,使用作用域解析符

SingingWaiter sw;
...
sw.Singer::show();

2,在子类重定义方法

对于使用作用域解析符的方法甚是繁杂。所以我们可以在子类中声明并定义一个自己的方法

void SingingWaiter::show(){
    Singer::show();
}

3,设置保护性继承

最后一种方式是将所有的数据组件都设置为保护的,而不是私有的,收方法的保护,外界不可以直接访问基类的方法,也就间接的防治了二义性的发生。

对于混合使用虚基类和非虚基类

假设A是B和C的虚基类,并作为D和E的非需基类,F类继承了B、C、D、E四个类。F对象中将会包含几个A对象。由于B、C是以虚基类方式继承了A所以这里只会产生一个A对象,但是对于D和E没有声明虚基类,就导致每个基类都会携带一个A对象。所以一共产生了3个A对象。


  1. Stephen Prata.C++ Primer Plus 6th.人民邮电出版社.2016.3 551~567
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值