【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,而是仅仅调用了它本身的虚构函数,再一次验证了,虚基类只调用一次的结论。
【c++】虚基类的更多相关文章
- 【C++】继承(虚基类)
类的继承与派生 面向对象技术强调软件的可重用性,这种重用性通过继承机制来实现.而在类的继承过程中,被重用的原有类称为基类,新创建的类称为派生类.派生类定义语法格式如下: class <派生类名& ...
- C++中 引入虚基类的作用
当某类的部分或全部直接基类是从另一个基类共同派生而来时,这直接基类中,从上一级基类继承来的成员就拥有相同的名称,派生类的对象的这些同名成员在内存中同时拥有多个拷贝,同一个函数名有多个映射.可以使用作用 ...
- C++ - 虚基类、虚函数与纯虚函数
虚基类 在说明其作用前先看一段代码 class A{public: int iValue;}; class B:public A{public: void bPrintf(){ ...
- 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类
[源码下载] 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 多重继承 虚基类 示例1 ...
- C++学习20 虚基类详解
多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如非常经典的菱形继承层次.如下图所示: 类A派生出类B和类C,类D继承自类B和类 ...
- 一目了然c++虚基类!
#include <IOSTREAM.H> //基类 class CBase ...{ protected: int a; public: CBase(int na) ...{ a=na; ...
- C++:虚基类
4.4.3 虚基类1.没什么要引入虚基类 如果一个类有多个直接基类,而这些直接基类又有一个共同的基类,则在最底层的派生类中会保留这个间接的共同基类数据成员的多分同名成员.在访问这些同名的成员时,必须在 ...
- 【c++内存分布系列】虚基类表
虚基类表相对于虚函数表要稍微难理解些,故单独提出来. 虚函数表是在对象生成时插入一个虚函数指针,指向虚函数表,这个表中所列就是虚函数. 虚基类表原理与虚函数表类似,不过虚基类表的内容有所不同.表的第一 ...
- C++ (P160—)多继承 二义性 虚基类 “向上转型”
1 多继承中,必须给每个基类指定一种派生类型,如果缺省,相应的基类则取私有派生类型,而不是和前一个基类取相同的派生类型 2 一个类的保护成员只能被本类的成员函数或者它的派生类成员函数访问 3 由于c+ ...
随机推荐
- int.Parse()、int.TryParse()和Convert.ToInt32()的区别
1:int.Parse(一个参数) 此参数必须满足: 1 只能是字符串: 2 只能是 “整型” 字符串,即各种整型ToString()之后的形式,也不能为浮点型. 2:int.TryPa ...
- Beta版本冲刺——day7
No Bug 031402401鲍亮 031402402曹鑫杰 031402403常松 031402412林淋 031402418汪培侨 031402426许秋鑫 站立式会议 今日计划表 人员 工作 ...
- 为什么上传文件的表单里面要加一个属性enctype=multipart/form-data?
首先知道enctype这个属性管理的是表单的MIME编码.共有三个值可选:1.application/x-www-form-urlencoded2.multipart/form-data3.text/ ...
- 【python】构造字典类型字典
字典类型字典:就是包含字典类型的字典,如{'sss': {'ss': 'dddsdsdsd'}} 构造方式: a={} b="sss" a[b]={} a[b]['ss'] = & ...
- Java BigDecimal和double
BigDecimal类 对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数 ...
- (C#) 使用Nullable类型
有个case,对一个double数设置初始值,然后,在程序运行中,为double赋值.(注意,也可能没有赋值). 这个时候,可以用Nullable 来设置初始值,在程序的最后做个判断. 参考:
- (转)Java:按值传递和按引用传递详细解说
值传递和引用传递详解: 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public class TempTest { private void test1(int a ...
- javascript、ECMAScript、DOM、BOM关系
ECMAScript,正式名称为 ECMA 262 和 ISO/IEC 16262,是宿主环境中脚本语言的国际 Web 标准. ECMAScript 规范定义了一种脚本语言实现应该包含的内容:但是,因 ...
- 第二周:Java For循环方法简介
1.for循环的作用 Java当中循环的意思就是让Java程序重复地执行某些语句.在程序设计时,常常需要处理大量的重复动作, 采用循环结构可以降低程序书写的长度和复杂度可使复杂问题简单化,提高程序的可 ...
- vs2008主题
http://www.cnblogs.com/xiaoshatian/archive/2009/11/20/1606440.html