C++:虚基类

来源:互联网 发布:奥拉朱旺数据 编辑:程序博客网 时间:2024/05/24 05:16

C++:虚基类

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


  • C虚基类
    • 声明虚基类
    • 新的构造函数规则
  • 方法的二义性
      • 1使用作用域解析符
      • 2在子类重定义方法
      • 3设置保护性继承
    • 对于混合使用虚基类和非虚基类

假如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 ↩
0 0
原创粉丝点击