目录

一.什么是虚继承

二.虚继承原理

三.虚继承使用注意事项


一.什么是虚继承

所谓虚继承(virtual)就是子类中只有一份间接父类的数据。该技术用于解决多继承中的父类为非虚基类时出现的数据冗余问题,即菱形继承问题。

小编用一张图来表述一下:

如果是下图这种非虚继承,那么D类中就会出现两个 int a,当我们用D实例化对象调用a时,编译会报错,因为发生了混淆。除非指定类域B或C。当然指定A也可以,因为默认会从第一个父类中找。

此时,D的实例化对象内部结构如下:

而当我们使用虚继承时,结构是下图这样,D中只有一份父类A,当我们调用A中数据时,并不会发生冗余。

此时,D对象内部结构是这样:

二.虚继承原理

在上图中,父类数据并不存放在虚继承的子类中,那么子类怎么找到父类数据呢?

——在虚继承的类中,会定义一个虚基表指针vbptr指向虚基表

而虚基表中会存在偏移量,这个量就是表的地址到父类数据地址的距离

我们可以通过调试,找到虚基表指针和虚基表:

首先,我们为每一个数据赋值,以便观察:

之后,调用监视,查看d对象地址和d中a数据地址:

再通过d的地址查看内存窗口,看d中内存分布:

由此我们可以分析得到对象d及其内部父类的内存布局:

在这个我们可能会有个疑问,那这B和C中两个是什么呢?

这就是虚基表指针

再通过内存窗口,查看一下虚基表指针指向的地址,根据我们的了解应该就是虚基表,而其中存有偏移量

偏移量,就是虚基表指针地址到父类数据地址的距离,这里以b中虚基表为例

到这里我们就能解释一个问题:为什么bptr和cptr能够找到并不位于自己内部的变量a?

因为bptr和cptr都对d进行了切片,当各自寻找变量a时,会从自身的虚基表指针中找到虚基表,通过虚基表的偏移量找到变量a的地址,从而找到了变量a。 

画图解释就是这样:

三.虚继承使用注意事项

当使用虚继承的时候,需要注意,虚继承只有在多继承时才有用。也就是说如果只有一层继承关系或者是单继承都将不起作用。

因为虚继承是保证子类中只有一个间接父类,说简单一点就是虚继承只能在隔代继承中起作用。

比如下面两种情况即便虚继承也没有意义:

(1)是因为虽然虚继承产生了虚基表和指针,但是class B并没有子类,而虚继承是用以保证子类只有一个间接父类class A。当然话说回来,就算有子类、哪怕多个子类,也都体现不出虚继承,因为虚继承要求同一个子类的多个父类继承自同一个间接父类,而该例只有一个父类class B

(2)是因为虽然class C虚继承了class B,但是class B是class A的非虚继承,那么B中就会有一份A。而class D对A是虚继承,就导致E在实例化时会存放一个对D而言公共的A。这样E中还是存放了两个A。调用变量时还是会混淆。

这样说可能还有些难懂,那换个说法,class B中没有虚基表指针,而D中有虚基表指针,当E从D调用int a时会从虚基表指针找到公共区域的A,而E从B中找只会在B的区域内找到int a。

画图表示E内部结构就是这样:

正确的继承关系应该是当class A的子类继承时,都是虚继承,这才能保证当有像class E这样的间接子类定义时,class在其中都只会在公共区域有一份。对本例来说即class B是虚继承。

只有两种编程语言:一种是天天挨骂的,另一种是没人用的——Bjarne Stroustrup(C++之父)


如有错误,敬请斧正

C++语法——详解虚继承相关推荐

  1. 继承详解(虚继承实现原理)

    继承的概念及定义 概念: ​ 继承机制是面向对象程序设计为了提高代码复用率的一种手段,它可以保持原类特性的基础上进行拓展,简单来说继承是类层次的复用. 接下来我们来看一个简单的继承 class Per ...

  2. 详解虚函数的实现过程之菱形继承(5)

    大家看到标题,会不会菱形继承的虚表会不会是重复的呢?祖父类的虚表会不会在子类会不会是两份相同呢?那么我们一起来探索一下吧,冲冲冲!! 首先我们来分析一下: 它一共定义了四个类,分别为CFurnitur ...

  3. 详解虚函数的实现过程之单继承(2)

    从汇编分析一下下面的多态模拟结构 利用 父类指针指向子类的特性,可以间接调用各子类中的虚函数. 虽然指针类型为父类,但由于虚表的排列顺序是按虚函数在类继承层次中首次声明的顺序依次排列的,因此,只要继承 ...

  4. python编程语法大全-Python编程入门——基础语法详解

    今天小编给大家带来Python编程入门--基础语法详解. 关于怎么快速学python,可以加下小编的python学习群:611+530+101,不管你是小白还是大牛,小编我都欢迎,不定期分享干货 每天 ...

  5. python编程语法-Python编程入门——基础语法详解

    今天小编给大家带来Python编程入门--基础语法详解. 一.基本概念 1.内置的变量类型: Python是有变量类型的,而且会强制检查变量类型.内置的变量类型有如下几种: #浮点 float_num ...

  6. python编程if语法-Python编程入门基础语法详解经典

    原标题:Python编程入门基础语法详解经典 一.基本概念 1.内置的变量类型: Python是有变量类型的,而且会强制检查变量类型.内置的变量类型有如下几种: #浮点 float_number = ...

  7. python编程语法-Python编程入门——基础语法详解(经典)

    今天小编给大家带来Python编程入门--基础语法详解.温馨提示: 亮点在最后! 在这里还是要推荐下我自己建的Python开发学习群:301056051,群里都是学Python开发的,如果你正在学习P ...

  8. 详解虚函数的实现过程之虚基类(4)

    博客虚函数实现过程3 时提到过虚基类,这里呢,我们来详细讲述一下: 当我们在虚函数的声明结尾处添加"=0",这种虚函数就被称为纯虚函数. 它好似一个没有实现只有声明的函数,它的存在 ...

  9. 详解虚函数的实现过程之多重继承(3)

    下面来一起探索一下多重继承时,有虚函数会怎么继承呢? 这里大家猜一下,SofaBed会占多少个字节呢? 首先我们是不是得猜一下它有几个虚表指针? 4* 4(4个int数据)+2*4(两个虚表指针)=2 ...

最新文章

  1. ASP.NET遍历配置文件的连接字符串
  2. 网站降权可从两方面着手分析
  3. 以下可以采用python语言保留字的是-模拟试卷C单项选择题
  4. jsp文件通常用common_JSP使用commons-fileupload实现文件上传实例
  5. 系列笔记 | 深度学习连载(4):优化技巧(上)
  6. POI 操作 Excel
  7. 可用计算机处理的多种信息载体的统称,广西壮族自治区2019-2020学年语文四年级下册第二单元测试卷B卷(6页)-原创力文档...
  8. 计算机Word2010在线做题,Word2010题库(答案)试题.doc
  9. java 常用前端框架_Java Web前端到后台常用框架介绍
  10. 计算机网络基础试题2,计算机网络基础试题库2
  11. 企业管理中使用凌云仓库管理软件免费版的优势
  12. c# winform实现人脸识别系统(文末附源码)
  13. 基于C/C++的弹出气泡框
  14. 蓝桥杯算法题-X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
  15. C语言实现线性回归求斜率
  16. 打开Beyond Compare报This license key has been revoked:
  17. groupby常用方法
  18. MySQL语法添加多个外码约束
  19. 从F型网页浏览看用户对网页的浏览习惯
  20. 王菲离婚后首发微博谈及与李亚鹏离婚原因

热门文章

  1. gitlab改成中文版(汉化)
  2. Java入门之Lambda表达式的应用
  3. android去电流程,android 去电流程
  4. 给大家分享一篇 Python:渗透测试开源项目「源码值得精读」
  5. 【财富空间】大势观澜2018:无问彷徨
  6. 用 Python 实现朋友圈中的九宫格图片
  7. nodejs multer封装 上传文件
  8. enumerate函数详解
  9. expression must have pointer-to-class type but it has type
  10. greenplum 源码解析 FTS辅助进程--ReadMe