【c++】虚基类

何要使用虚基类:

  为何避免多层继承中出项多个公共基类所造成的歧义现象

虚基类用法

  派生类继承基类时,加上一个virtual关键词则为虚拟基类继承。

在上图程序运行中,我们发现class bass的构造函数只调用了一次,因此obj.a就不会产生二义性了。

问题1:

  在这我们要特别留意下obj.a的结果123,为何它不是122也不是124,偏偏是123呢?

构造函数调用的顺序:

  

  从结果可以看出,从最底层派生类grand开始查找,我们发现grand先调用虚基类derive_v的构造函数;对derive_v而言,它同样开始先调用的虚基类base_V函数,即先输出”CONS base_V“,接着调用基类base的构造函数输出"CONS base",再输出"CONS derive_v";接着grand开始调用其基类derive,本应可获得输出结果"CONS base_V","CONS base"但class base_V是虚基类,也就是说明基类优先调用。

由下面的例子我们在进一步说明构造函数调用的顺序

虽然说派生类B和派生类C有一个公共的虚基类,但是两个类是相互独立的因此,另外由于B是优先创造C故调用顺序为A,B,A,C;

接着继续讨论下面的输出结果,我们发现输出中并没有出现类J,这是为何?由最低成派生类D可以看到,D中有两个基类,两个子对象,但是请注意“J*ptr"这仅仅声明了一个指针,而非对象,也就是说D中仅有一个子对象“m”,因此J中的构造函数不会调用也因此输出结果中并没有”J“;回过头来继续看结果,我们发现基类A是最先调用的,而且其被赋值为12,我们继续由最底层派生类D往上看,发现基类B的声明是先于基类C的,也就是说基类B要先于基类C被调用,我们已经知道了基类B有一个虚基类A,也就是虚基类A最先调用接着我们看派生类D的第二个基类C,对于这个基类我们有结果发现它并没有再一次调用与B共有的虚基类A,而是仅仅调用了它本身的虚构函数,再一次验证了,虚基类只调用一次的结论。

时间: 2024-10-11 12:41:26

【c++】虚基类的相关文章

C++中虚基类

摘自<C++程序设计> 如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员. C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员. 下面举例说明: 在如下的图中: Person类是Student和Teacher的基类,而Graduate类又继承自Student和Teacher类. 如果使用虚基类的话,Graduate将有两份age拷贝,两份gender拷贝,两份name

C++的虚基类知识点

当在多条继承路径上有一个公共的基类,在这些路径的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类. class x1:virtual public x{//... ...};class x2:virtual public x{//... ...};虚基类的初始化 虚基类(虚拟继承)的初始化与一般多继承的初始化在语法上是一样的,但构造函数的调用次序不同. 派生类的构造函数的调用次序有三个原则:(1)虚基类的构造函数在非虚基类之

第十二周 阅读项目 (4)虚基类多重继承数据理解

<span style="font-size:18px;">/* *Copyright (c)2014,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:d.cpp *作 者:张旺华 *完成日期:2015年6月1日 *版 本 号:v1.0 */ #include<iostream> using namespace std; class A { public: int n; }; class B:virtual public A

C++虚基类详解

1.虚基类的作用从上面的介绍可知:如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员.在引用这些同名的成员时,必须在派生类对象名后增加直接基类名,以避免产生二义性,使其惟一地标识一个成员,如    c1.A::display( ).在一个类中保留间接共同基类的多份同名成员,这种现象是人们不希望出现的.C++提供虚基类(virtual base class )的方法,使得在继承间接共同基类时只保留一份成员.现在,将类A声明为

虚基类练习:动物(利用虚基类建立一个类的多重继承,包括动物(animal,属性有体长,体重和性别),陆生动物(ter_animal,属性增加了奔跑速度),水生动物(aqu_animal,属性增加了游泳速度)和两栖动物(amp_animal)。)

Description 长期的物种进化使两栖动物既能活跃在陆地上,又能游动于水中.利用虚基类建立一个类的多重继承,包括动物(animal,属性有体长,体重和性别),陆生动物(ter_animal,属性增加了奔跑速度),水生动物(aqu_animal,属性增加了游泳速度)和两栖动物(amp_animal).其中两栖动物保留了陆生动物和水生动物的属性. Input 两栖动物的体长,体重,性别,游泳速度,奔跑速度(running_speed) Output 初始化的两栖动物的体长,体重,性别,游泳速度

C++:虚基类

4.4.3 虚基类1.没什么要引入虚基类 如果一个类有多个直接基类,而这些直接基类又有一个共同的基类,则在最底层的派生类中会保留这个间接的共同基类数据成员的多分同名成员.在访问这些同名的成员时,必须在派生类对象后增加直接基类名,使其惟一地标识一个成员,以免产生二义性. //例 4.15 虚基类的引例 #include<iostream> using namespace std; class Base{ //声明类Base1和类Base2的共同的基类Base public: Base() { a

C++中 引入虚基类的作用

当某类的部分或全部直接基类是从另一个基类共同派生而来时,这直接基类中,从上一级基类继承来的成员就拥有相同的名称,派生类的对象的这些同名成员在内存中同时拥有多个拷贝,同一个函数名有多个映射.可以使用作用域分辨符来唯一标识并分别访问它们.也可以将共同基类设置为虚基类,这时从不同的路径继承过来的同名数据成员在内存中只拥有一个拷贝,同一个函数名也只有一个映射.也就是说虚基类解决了同名成员的唯一标识问题.

虚基类的用法

1 #include <iostream> 2 3 using namespace std; 4 5 class A 6 { 7 private: 8 int a; 9 public: 10 A(int x):a(x){} 11 void show() const 12 { 13 cout<<"a: "<<a<<endl; 14 } 15 ~A(){} 16 }; 17 class B:virtual public A //定义虚基类的用

虚基类初始化问题

在包含有继承关系的类里,生成一个派生类对象,要调用构造函数进行初始化此对象,而构造函数的调用顺序是先调用最顶层基类的构造函数,次顶层....等:但在普通继承和虚继承里存在区别 普通继承:父类只能由其直接派生类初始化 1 class A 2 { 3 char a; 4 public: 5 A(char _a) :a(_a){ cout << a << endl; } 6 }; 7 8 class B:public A 9 { 10 char b; 11 public: 12 B(ch

一目了然c++虚基类!

1 #include <IOSTREAM.H> 2 //基类 3 class CBase 4 ...{ 5 protected: 6 int a; 7 public: 8 CBase(int na) 9 ...{ 10 a=na; 11 cout<<"CBase constructor! "; 12 } 13 14 ~CBase()...{cout<<"CBase deconstructor! ";} 15 }; 16 17 //