C++学习-多继承和虚基类

转载 2015年11月18日 10:29:21

本文主要是讨论类的多继承,多继承的方式可使派生类具有多个基类的特性。以下是一个继承关系,C从A和B基类中派生出来,在派生类C中,包含了基类A与基类B的成员,还有C类自己的成员。

在上述关系图中,可以看到,类继承的结构很清晰,但在很多时候,有可能有以下继承关系:


在这幅类的继承关系图中可以看到,B1和B2分别继承于A,再由B1和B2派生出C,这关系看起来很简单,但在内部,有点麻烦?
产生二义性。
A派生出B1和B2,所以B1和B2中分别包含A的成员,再由B1和B2派生出C,此时C包含了B1和B2类的成员,所以C中总共有2个A成员。这时候麻烦了,如何要对C类中B1父类中的A类成员修改,或者是对C类中的B2父类中的A类成员修改呢?这有点绕口,C++提供了一种方法是通过作用域来指定,可以参考前一篇博文《C++学习-继承中的作用域(10)

这里给一个简单的例子:



执行结果:
B1::mA = 30
B2::mA = 50
mB1 = 20
mB2 = 40
mC = 10

从这个例子可以看到,使用作用域运算符"::"来消除二义性,这样就能巧妙地避免那个棘手的问题。不过在类C中,包含了2个A的部分,有点浪费空间。当然C++是非常伟大的,还有另一种更好的办法,就是使用虚基类,也可以称为虚继承。
虚基类的作用:使用虚基类能够在多重派生的过程中,使公有的基类在派生类中只有一个拷贝,这样就能解决上述二义性的错误。如果使用虚基类,那么以上类C当中也就只有1个A的部分。在虚基类的使用过程中,还有一个非常重要的特性,看例子便可发现
看例子:



执行结果:
B1::mA = 0
B2::mA = 0
mA = 0
mB1 = 20
mB2 = 40
mC = 10

B1::mA = 163
B2::mA = 163
mA = 163
mB1 = 20
mB2 = 40
mC = 10

对比一下这两个例子,差别很小,将作用域的调用方式给去掉了。在这个例子当中,使用了virtual方式继承了基类A,所以在B1和B2中,对类A只有一个拷贝,若使用virtual方式继承,不管派生多少派生类,类A永远只有一个拷贝。对mA进行修改,从B1或B2调用mA,都是调用同一个副本,从结果可以看出这一结论。
重要:
虚基类的构造函数的调用方法与一般基类的构造函数的调用方法是不同的
。在这个例子中,编译器没有调用B1或者B2的构造函数来调用基类A的构造函数,因为在虚继承过程中,基类A只有一个拷贝,所以编译器无法确定应该由类B1或者类B2的构造函数来调用基类A的构造函数,所以此时调用的是基类A的默认构造函数,所以刚开始mA的结果为0,是基类A的默认构造函数设置的默认值。

C++规定,由虚基类经过一次或者多次派生出来的派生类,在其每一个派生类的构造函数的成员初始化列表中必须给出对虚基类的构造函数的调用,如果未列出,则调用虚基类的默认构造函数。
在本例当中,在执行B1和B2的构造函数时都不调用虚基类A的构造函数,而是在类C中的构造函数直接调用虚基类A的默认构造函数。(因为编译器无法确定)
再看一个与上面几乎是一样的例子,只有一个区别,就是在类C的初始化列表中显示的调用虚基类A的构造函数,如下:



执行结果:
B1::mA = 20
B2::mA = 20
mA = 20
mB1 = 20
mB2 = 40
mC = 10

B1::mA = 163
B2::mA = 163
mA = 163
mB1 = 20
mB2 = 40
mC = 10

唯一的区别就是这行代码:
C(int x, int a, int b, int c, int d) : A(a), B1(a, b), B2(c, d), mC(x) {}
在这里显示地调用虚基类A的构造函数,并传入初始值,所以第一次打印mA的值不是0,而是20。



c++多继承与虚基类

转载自:http://blog.csdn.net/insistgogo/article/details/6653301 多继承的定义:派生类的基类大于一个 语法: [...
  • liguohanhaha
  • liguohanhaha
  • 2016年04月11日 20:26
  • 542

<C++略识>之多重继承、多继承、虚继承

问题:什么是多重继承? 定义三个类:人、士兵、步兵,则有:步兵士兵人,这样的关系称之为多重继承,写法如下:class Person { }; classSoldier:publicPerson ...
  • u013003827
  • u013003827
  • 2016年07月22日 22:29
  • 3386

c++继承之虚基类

虚基类的概念:        若在多继承派生类中继承的基类再拥有一个公共基类,则这个公共基类会在多继承派生类的对象中产生多个公共基类子对象,如果要使这个公共基类再多继承派生类中只产生一个基类子对象,则...
  • erlian1992
  • erlian1992
  • 2015年03月11日 20:56
  • 1190

C++虚基类和多继承

1、首先虚基类解决的是什么问题? 如果一个子类继承的父类不止一个的时候,比如一个子类会继承两个父类。如 class A { private: int x; } class B { p...
  • weixin_37871174
  • weixin_37871174
  • 2017年09月24日 15:33
  • 59

C++多继承和虚基类

本文属学习笔记,如有错误,欢迎拍砖!在上一篇《C++和Java的多继承》中我们说到了c++多继承中如果子类D的父类中有两个或两个以上(如父类B,C)又继承自一个类(如A,那么在子类D中访问继承得来的属...
  • sycflash
  • sycflash
  • 2010年03月17日 09:03
  • 752

C++之虚函数(三)虚继承和虚基类详解

多继承(Multiple Inheritance)是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名...
  • Bruce_0712
  • Bruce_0712
  • 2017年02月18日 10:52
  • 387

C++虚继承和虚基类;虚函数与继承

定义:在C++中,在定义公共基类的派生类的时候,如果在继承方式前使用关键字virtual...
  • cyuyanchenxi
  • cyuyanchenxi
  • 2017年03月28日 23:05
  • 465

抽象类和虚基类的定义及用途

抽象类不能实例化对象! 为了让一个类成为抽象类,至少必须有一个纯虚函数。包含至少一个纯虚函数的类视为抽象类! classA { public: virtual void lock(void)=0; ...
  • qq_32175379
  • qq_32175379
  • 2016年12月21日 19:41
  • 1710

c++中的 虚函数 纯虚函数 虚基类

原文出自http://blog.csdn.net/dardgen/article/details/18790977 虚函数 ,纯虚函数, 虚基类,它们都和virtual有关,这三个带有虚字的...
  • a345203172
  • a345203172
  • 2014年03月21日 10:07
  • 4782

C++多态、接口和虚基类的深入理解

1. 多态 表述一:在面向对象语言中,接口的多种不同实现方式即为多态。多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数。 表述二:基类指针(或引用)的多种状态,即...
  • kingsir2020
  • kingsir2020
  • 2016年08月03日 22:18
  • 996
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++学习-多继承和虚基类
举报原因:
原因补充:

(最多只允许输入30个字)