虚继承是如何解决二义性和数据的冗余的

news2024/11/26 15:00:38

我们知道面向对象的三大特性分别为封装,继承,多态。在继承中,我们知道一个类可以继承另一个类,这样的关系被叫做子类(派生类)继承父类(基类),并且子类可以使用到父类的接口。但是在C++中还被设计了一个多继承,是什么意思呢。指的就是一个类可以继承多个类,就好比一个人可能他在这个学校担任老师,但是在另一边他可能是某个资历更深老师的某个学生,这样也产生了,如果一个老师类里面有名称了,学生里面也有一个名称,不可能他担任老师的时候叫做张三,担任学生的时候又叫做王五了。这里也就是二义性。但是我们可以通过对数据的指定性来解决二义性的问题,例如写下这样一段代码

 代码中写到,B继承了A,C继承了A,D继承了B,C,且作为基类中的A有一个_a的成员变量。可以大致把他们理解为这样的关系

 

 这就是一个菱形继承。接下来我们通过内存去看它们 

 通过对d的取地址观察我们可以看到确实是解决了数据二义性,但是数据的冗余是如何去处理的呢。这里我们可以用到一个虚继承,虚继承主要解决的就是命名冲突和数据冗余的问题,只保留一份基类的成员,关键字是virtual。当我们把关键字加上去之后再去对d取地址看到的内容就是这样的

 

 

 当把虚继承关键字加上去再去观察内存的时候明显发现,此时B,C类中原本为A的数据区被写道了最后一个位置,而原本的位置变成了一个地址,如果我们通过地址找过去看看又会发现什么

 

 通过地址过去之后发现第一个数据是00 00 00 00是因为它需要给其它的值预留空间,但是第二个值分别是十六进制的14,0c,对应的也就是十进制的20,和12。但是这两个值能代表什么呢。如果我们对比一下就能发现,从地址开始,B便宜20字节之后刚好是到A类,而C类偏移12字节后也恰好是到A类。

那么这个偏移量是用来干什么的呢。我们拿这样一段代码来举例。

在没有使用虚继承之前它的存储方式会是这样 

但是当使用了虚继承之后它的模型也会跟着发生变化

 

 可以看到b对象的模型也跟着发生了变化,也是一个指针指向一块区域,区域内存放着偏移量。

此时,我们利用B类定义一个对象,然后在用B类定义一个指针,让指针指向这个对象并且对对象中的_a进行操作,然后在让这个指针指向对象d,同样对d对象中的_a进行操作,那么此时的指针是无法知道具体指向谁的,它可能指向b对象,也可能指向d对象,所以这是就会利用偏移量,加上偏移量的值之后无论是b还是d都可以找到_a。

 当我们从反汇编的角度来看它的时候,也可以看到它是先利用当前的地址去加上偏移量来找到_a

 

 可能会有疑惑,为什么不能把地址直接存在对象里面,却偏偏要弄一个地址出来去存到那里,因为是要考虑到如果里面有多个值的情况,一个值就要一个地址,多个值就会造成对象空间的变大,所以会用一个指针来维护,管理一块区域。我们可以通过多加一个对象来观察确定。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/778430.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch学习--数据聚合

介绍 数据聚合可以帮助我们对海量的数据进行统计分析,如果结合kibana,我们还能形成可视化的图形报表。自动补全可以根据用户输入的部分关键字去自动补全和提示。数据同步可以帮助我们解决es和mysql的数据一致性问题。集群可以帮助我们了解结构和不同节点…

Pytorch个人学习记录总结 08

目录 神经网络-搭建小实战和Sequential的使用 版本1——未用Sequential 版本2——用Sequential 神经网络-搭建小实战和Sequential的使用 torch.nn.Sequential的官方文档地址,模块将按照它们在构造函数中传递的顺序添加。代码实现的是下图: 版本1—…

BeanFactory容器的构建和使用示例

BeanFactory容器的实现流程: BeanFactory是Spring框架中的一部分,它提供了IoC(控制反转)的实现机制。下面是BeanFactory的IoC实现过程: 定义Bean定义:首先,我们需要在配置文件中定义Bean的定义…

[数据结构]顺序表和ArrayList

顺序表的介绍 在了解顺序表之前先了解一下什么叫做线性表: 线性表(linear list):是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。 常见的线性表:顺序表、链表、栈、队列… 线性…

数学建模入门-如何从0开始,掌握数学建模的基本技能

一、前言 本文主要面向没有了解过数学建模的同学,帮助同学们如何快速地进行数学建模的入门并且尽快地在各类赛事中获奖,或者写出优秀的数学建模论文。 在本文中,我将从什么是数学建模、数学建模的应用领域、数学建模的基本步骤、数学建模的技…

两天学会用Webpack打包前端代码-day01

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 什么是 Webpack? 使用 Webpack 体验webpack打包过程 修改 Webpack 打包入口和出口 入口 出…

[JAVAee]线程安全

目录 线程安全的理解 线程不安全的原因 ①非原子性 ②可见性 ③代码重排序 体会何为不安全的线程 保证线程安全 一个代码在多线程的环境下就很容易出现错误. 线程安全的理解 线程安全是什么呢?通俗的来讲,线程安全就是在多线程的环境下,代码的结果是符合我们预期的,就…

R语言-数据分析及建模(第1节)分类与预测问题简介

小伙伴们,今天我们学习R语言-数据分析及建模(第1节)分类与预测问题简介 01-分类与预测问题简介 ◆分类和预测是预测问题的两种主要类型,分类主要是预测分类标号(离散属性) ,而预测主要是建立连续…

Windows11的VS201x编译OpenCV+Contrib+CUDA

(1) CUDA下载,注意要和cudnn版本号相关。 我安装的是cuda11.0,注意VS2015不能编译CUDA11,所以用VS2015的话需要下载CUDA 10。因为更高的版本目前还没有cudnn。 (2) 下载和安装VS2015。 (3) 下载和解压CMake。 CMake地址: Releases Kitw…

性能测试Ⅱ(压力测试与负载测试详解)

协议 性能理论:并发编程 ,系统调度,调度算法 监控 压力测试与负载测试的区别是什么? 负载测试 在被测系统上持续不断的增加压力,直到性能指标(响应时间等)超过预定指标或者某种资源(CPU&内存)使用已达到饱和状…

每天五分钟机器学习:多项式非线性回归模型

本文重点 在前面的课程中,我们学习了线性回归模型和非线性回归模型的区别和联系。多项式非线性回归模型是一种用于拟合非线性数据的回归模型。与线性回归模型不同,多项式非线性回归模型可以通过增加多项式的次数来适应更复杂的数据模式。在本文中,我们将介绍多项式非线性回…

[SpringMVC]仿写SpringMVC(注解开发)

文章目录 前提:1、代码结构2、核心:YhzMVC3、初始化步骤是:4、执行 前提: 当前版本无接受网络请求功能,不喜勿喷🙏🙏 本文将对代码核心进行讲解,源码已上传到gitee仓库 1、代码结构…

SpringBoot集成Druid实现数据库连接池

一、引入依赖 完整的pom文件如下所示: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

第四讲:MySQL中DDL一些基本数据类型及表的创建、查询

目录 1、创建表:2、DDL一些基本数据类型&#xff1a; 1、创建表: 部分单词及解析&#xff1a; 1、tables:表 2、comment:评论&#xff0c;解释 3、gender:性别 4、neighbor&#xff1a;邻居 1、创建表&#xff1a;&#xff08;注&#xff1a;在自定义数据库操作&#xff0c;…

Vue--》打造个性化医疗服务的医院预约系统(二)

今天开始使用 vue3 + ts 搭建一个医院预约系统的前台页面,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GithHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关…

分布式锁:Redis、Zookeeper

1.基于Redis实现分布式锁&#xfeff; Redis分布式锁原理如上图所示&#xff0c;当有多个Set命令发送到Redis时&#xff0c;Redis会串行处理&#xff0c;最终只有一个Set命令执行成功&#xff0c;从而只有一个线程加锁成功 2.SetNx命令加锁 利用Redis的setNx命令在Redis数据库…

01 openEuler操作系统介绍

文章目录 01 openEuler操作系统介绍1.1 发布件1.2 最小硬件要求1.3 硬件兼容性1.4 关键特性1.4.1 openEuler 22.03-LTS基于 Linux Kernel 5.10 内核构建, 在进程调度、内存管理等方面带来10余处创新1.4.2 新介质文件系统1.4.3 内存分级扩展1.4.4 用户态协议栈1.4.5 云原生调度增…

【人工智能】深度优先搜索、代价一致搜索、深度有限搜索、迭代深度优先搜索、图搜索

【人工智能】无信息搜索—BFS 、代价一致、DFS、深度受限、迭代深入深度优先、图搜索 什么是搜索 搜索问题是指既不能通过数学建模解决,又没有其他算法可以套用或者非遍历所有情况才能得出正确结果。这时就需要采用搜索算法来解决问题。搜索就是一种通过穷举所有解的状态,来…

【车载开发系列】AUTOSAR DemDTCAttributes

【车载开发系列】AUTOSAR DemDTCAttributes 【车载开发系列】AUTOSAR DemDTCAttributes 【车载开发系列】AUTOSAR DemDTCAttributes一. DemDTCAttributes概念二. DemAgingCycleCounterThreshold三. DemAgingAllowed四. DemDTCPriority五. DemImmediateNvStorage六. DemMaxNumbe…

BatchNorm, LayerNorm, InstanceNorm和GroupNorm

1. 介绍 Batch Norm: 对NHW计算归一化参数(均值和方差)&#xff0c;总共得到C组归一化参数, 相当于对每个channel进行归一化。BN主要缺点是对batchsize的大小比较敏感&#xff0c;由于每次计算均值和方差是在一个batch上&#xff0c;所以如果batchsize太小&#xff0c;则计算的…