何要使用虚基类:

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

虚基类用法

  派生类继承基类时,加上一个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++】虚基类的更多相关文章

  1. 【C++】继承(虚基类)

    类的继承与派生 面向对象技术强调软件的可重用性,这种重用性通过继承机制来实现.而在类的继承过程中,被重用的原有类称为基类,新创建的类称为派生类.派生类定义语法格式如下: class <派生类名& ...

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

    当某类的部分或全部直接基类是从另一个基类共同派生而来时,这直接基类中,从上一级基类继承来的成员就拥有相同的名称,派生类的对象的这些同名成员在内存中同时拥有多个拷贝,同一个函数名有多个映射.可以使用作用 ...

  3. C++ - 虚基类、虚函数与纯虚函数

    虚基类       在说明其作用前先看一段代码 class A{public:    int iValue;}; class B:public A{public:    void bPrintf(){ ...

  4. 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类

    [源码下载] 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 多重继承 虚基类 示例1 ...

  5. C++学习20 虚基类详解

    多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如非常经典的菱形继承层次.如下图所示: 类A派生出类B和类C,类D继承自类B和类 ...

  6. 一目了然c++虚基类!

    #include <IOSTREAM.H> //基类 class CBase ...{ protected: int a; public: CBase(int na) ...{ a=na; ...

  7. C++:虚基类

    4.4.3 虚基类1.没什么要引入虚基类 如果一个类有多个直接基类,而这些直接基类又有一个共同的基类,则在最底层的派生类中会保留这个间接的共同基类数据成员的多分同名成员.在访问这些同名的成员时,必须在 ...

  8. 【c++内存分布系列】虚基类表

    虚基类表相对于虚函数表要稍微难理解些,故单独提出来. 虚函数表是在对象生成时插入一个虚函数指针,指向虚函数表,这个表中所列就是虚函数. 虚基类表原理与虚函数表类似,不过虚基类表的内容有所不同.表的第一 ...

  9. C++ (P160—)多继承 二义性 虚基类 “向上转型”

    1 多继承中,必须给每个基类指定一种派生类型,如果缺省,相应的基类则取私有派生类型,而不是和前一个基类取相同的派生类型 2 一个类的保护成员只能被本类的成员函数或者它的派生类成员函数访问 3 由于c+ ...

随机推荐

  1. JS转换HTML转义符

    JS转换HTML转义符 //去掉html标签 function removeHtmlTab(tab) { return tab.replace(/<[^<>]+?>/g,'') ...

  2. 【python】pickle模块

    持久性的基本思想很简单.假定有一个 Python 程序,它可能是一个管理日常待办事项的程序,您希望在多次执行这个程序之间可以保存应用程序对象(待办事项).换句话说,您希望将对象存储在磁盘上,便于以后检 ...

  3. open office操作word文档

    前段时间工作需要使用open office往word中写文件,写图片,以及向footer也就是页尾中插入图片,已经封装成了类,直接调用即可,代码如下: package com.test.common. ...

  4. apache 使用 .htaccess 导致500错误

    今天在win主机上配置了一个apache+mysql+php 的环境,一切看似正常了.结果将程序转移过来,打开网站的时候,出现了500错误.于是乎查原因: 首先,怀疑的是连接mysql出错了,找出配置 ...

  5. Rails :布局和视图渲染

    原文地址: http://guides.ruby-china.org/layouts_and_rendering.html Rails 布局和视图渲染 本文介绍 Action Controller 和 ...

  6. JSP中动态include和静态include的区别(简版)

    动态的include: 用法:<jsp:include page="1.jsp" flush="true" /> 特点:行为元素,可以带参数:先编译 ...

  7. 关于request.getParameterMap()的类型转换和数据获取

    首先po上一个自己写的转换类. /** * @author Xfiler * @described 将request.getParameterMap()转换为普通的Map的工具方法 * @param ...

  8. System.Data.OleDb.OleDbException: 未指定的错误的解决方法

    异常详细信息: System.Data.OleDb.OleDbException: 未指定的错误 这个错误是access数据库特有的错误,当access频繁读取或操作过多的时候就会发生这个错误,微软官 ...

  9. 免费SVN空间

    推荐免费的svn空间(SVN代码托管) 最近研究了国内和国外的免费svn空间,SVN代码托管,SVN在线,代码托管中心,有所心得. 1.http://www.svn999.com/ [推荐]国内的,免 ...

  10. 原生js获取元素style属性

    function getStyle(ele,attr){ if( ele.currentStyle ){ return ele.currentStyle[attr]; // ie } else { r ...