当前位置: 首页 > news >正文

如何解决多继承下的 菱形继承 问题

目录

概念:

菱形虚拟继承:


概念:

 

 

此时D类属于多继承,可以看到D类里面会有两份A类的数据,菱形继承也并不一定就一定就是上图的菱形,假如B类下面还有一个类,D类继承它,同样也是菱形继承问题

class A
{
public:int a;
};class B : public A
{
public:int b;
};class C : public A
{
public:int c;
};class D : public B, public C
{
public:int d;
};int main()
{D data;cout << data.a << endl;return 0;
}

 大家觉得这段代码有问题嘛?

 

我们此时D类已经出现了数据冗余和二义性的问题了,我们直接访问 a 的值是不可行的,只有明确地表明你要访问地是哪个类里面的 a

class A
{
public:int a;
};class B : virtual public A
{
public:int b;
};class C : virtual public A
{
public:int c;
};class D : public B, public C
{
public:int d;
};int main()
{D data;cout << data.a << endl;return 0;
}

 不过可以在腰部,也就是 B和C 类加上 virtual ,就可以数据二义性的问题和数据冗余,这个叫 菱形虚拟继承

菱形虚拟继承:

class A
{
public:int a;
};//class B : virtual public A
class B : public A
{
public:int b;
};//class C : virtual public A
class C : public A
{
public:int c;
};class D : public B, public C
{
public:int d;
};int main()
{D data;//data.a = 1;data.B::a = 2;data.C::a = 6;data.b = 3;data.c = 4;data.d = 5;return 0;
}

 我们来看一下上述代码运行完,在内存的角度观察他们的变化:

 

能够看的出,总共分为三个部分:上面两个框分别是B和C类的,谁先继承谁就在上面,并且,数据a 也是独立开来的,B里面a = 2;C里面a = 6 。 

再来看加了virtual后的又会是什么样的变化: 

 

同样也是分为了三个部分,先继承的类就在上面,所以上面两个分别是B和C类,但这次不一样的是:

数据a并没有分开来,而是在最下面去了,相代替的是一个指针,这个指针指向的是一个虚基表,这个表里面存放着一个偏移量,当我们要进行 切割 的时候,获取 数据a 就通过当前的这个指针 + 这个偏离量就能找到了。(这个表叫虚基表,指针叫虚基表指针)

如果此时定义一个B对象,它的里面同时也有一个续集表指针,指向一个自己的续集表,这个偏移量 和 D定义出来的 对象 里的 B类的虚基表里的偏离量不同 

 

如图所示:左边是B类定义出来的对象;右边是D类定义出来的对象。

他们都有各自的虚基表指针,这个指针是不一样的!!!!里面的偏移量也是!! 

相关文章:

如何解决多继承下的 菱形继承 问题

目录 概念&#xff1a; 菱形虚拟继承: 概念&#xff1a; 此时D类属于多继承&#xff0c;可以看到D类里面会有两份A类的数据&#xff0c;菱形继承也并不一定就一定就是上图的菱形&#xff0c;假如B类下面还有一个类&#xff0c;D类继承它&#xff0c;同样也是菱形继承问题 cla…...

rk3288-android8.1-以太网ethernet和蓝牙Bluetooth

遇到一个现象,以太网和蓝牙打不开 经过不断分析和查找发现问题在.config中 CONFIG_MOTORCOMM_PHYy 会导致以太网的eth0注册不成功(现在是双网口,还有个USB网卡) 改成# CONFIG_MOTORCOMM_PHY is not set 后以太网可以正常 # CONFIG_RTC_DRV_RK808 is not set 会导致蓝牙打不…...

算法比赛——必备的数论知识

秋名山码民的主页 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f64f;作者水平有限&#xff0c;如发现错误&#xff0c;还请私信或者评论区留言&#xff01; 目录一、欧几里得二、扩展欧几里得三、算术基本定理四、线性筛选求质数五…...

Docker概述

什么是Docker我们要学习在Linux(RockyLinux)中安装使用Docker来配置软件的功能Docker是一个用来开发、运输和运行应用程序的开放平台。使用Docker可以将应用程序与基础结构分离&#xff0c;以便快速交付软件。使用Docker&#xff0c;您可以以管理应用程序的方式管理基础架构。通…...

实验室设计建设方案主要内容

实验室设计建设整体解决方案SICOLAB需要综合考虑实验室的功能需求、空间布局、设备选型、安全防护、节能环保等多方面因素。以下是一个基本的实验室设计建设方案的流程&#xff1a;一、需求分析&#xff1a;了解实验室的使用目的、实验内容、使用人数、设备种类、实验标准等&am…...

华为OD机试真题Python实现【日志采集系统】真题+解题思路+代码(20222023)

日志采集系统 题目 日志采集是运维系统的的核心组件。日志是按行生成,每行记做一条,由采集系统分批上报。 如果上报太频繁,会对服务端造成压力; 如果上报太晚,会降低用户的体验; 如果一次上报的条数太多,会导致超时失败。 为此,项目组设计了如下的上报策略: 每成功上…...

Python的模块与工具包

模块 模块是一个Python文件&#xff0c;以 .py结尾。模块能定义函数&#xff0c;类和变量&#xff0c;模块里也能包含可执行的代码。 作用 python 中有很多各种不同的模块&#xff0c;每一个模块都可以帮助我们快速的实现一些功能&#xff0c;比如实现和时间相关的功能就可以…...

联合熵和条件熵

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;information-theory】&#xff0c;需要的朋友们自取。或者公众号【AIShareLab】回复 信息论 也可获取。 文章目录联合熵条件熵联合…...

华为OD机试真题Python实现【求最大数字】真题+解题思路+代码(20222023)

求最大数字 题目 给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。 如34533,数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值4533 请返回经过删…...

Python爬虫(10)selenium爬虫后数据,存入csv、txt并将存入数据并对数据进行查询

之前的文章有关于更多操作方式详细解答&#xff0c;本篇基于前面的知识点进行操作&#xff0c;如果不了解可以先看之前的文章 Python爬虫&#xff08;1&#xff09;一次性搞定Selenium(新版)8种find_element元素定位方式 Python爬虫&#xff08;2&#xff09;-Selenium控制浏览…...

Python 之 Pandas 时间函数 time 、datetime 模块和时间处理基础

文章目录一、time 模块1、时间格式转换图2. struct_time 元组元素结构3. format time 结构化表示二、datetime 模块1. date类2. 方法和属性3. datetime 类三、timedelta 类的时间加减四、时间处理基础Python 中提供了对时间日期的多种多样的处理方式&#xff0c;主要是在 time …...

C语言学习及复习笔记-【5】C 运算符

文章目录5. C 运算符5.1 关系运算符5.2 逻辑运算符5.3 位运算符5.4 杂项运算符 ↦ sizeof & 三元5.5 例子1). 利用异或 ^ 来交换两个数的值&#xff0c;而且不引入其他变量。2). 利用位与 & 运算&#xff0c;判断一个整数是否是2的整数次幂。3). 不同长度的数据进行位运…...

数仓、数据湖、湖仓一体、数据网格

第一代&#xff1a;数据仓库 定义 为解决数据库面对数据分析的不足&#xff0c;孕育出新一类产品数据仓库。数据仓库&#xff08;Data Warehouse&#xff09;是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策和信息的全局共享。 数…...

C语言【atoi函数】

C语言【atoi函数】&#x1fac5;系统atoi函数&#x1fac5; 模拟实现atoi函数看到atoi函数&#xff0c;有人又会问有这个函数&#xff0c;我怎么没用过。那就说明&#xff1a;不是你刷题太少&#xff0c;就是atoi函数存在感太低。 这篇函数就带你领略atoi函数的魅力 &#x1fa…...

一起学习用Verilog在FPGA上实现CNN----(八)integrationFC设计

1 integrationFC设计 LeNet-5网络结构全连接部分如图所示&#xff0c;该部分有2个全连接层&#xff0c;1个TanH激活层&#xff0c;1个SoftMax激活层&#xff1a; 图片来自附带的技术文档《Hardware Documentation》 integrationFC部分原理图&#xff0c;如图所示&#xff0c;…...

面试题总结

1.js的数据类型 分为基本数据类型和引用数据类型。 基本数据类型 ES5的5种&#xff1a;Null&#xff0c;undefined&#xff0c;Boolean&#xff0c;Number&#xff0c;String&#xff0c; ES6新增&#xff1a;Symbol表示独一无二的值 ES10新增&#xff1a;BigInt 表示任意大的…...

go进阶(1) -深入理解goroutine并发运行机制

并发指的是同时进行多个任务的程序&#xff0c;Web处理请求&#xff0c;读写处理操作&#xff0c;I/O操作都可以充分利用并发增长处理速度&#xff0c;随着网络的普及&#xff0c;并发操作逐渐不可或缺 一、goroutine简述 在Golang中一个goroutines就是一个执行单元&#xff…...

mongodb 操作记录

#启动服务 net start MongoDB #停止服务 net stop MongoDB #进入mongo shell 方式 mongo db #查看当前数据库是那个 #插入一条数据 db.runoob.insert({x:10}) #查找数据 db.runoob.find() 查询所有的数据库 show dbs #连接mongodb mongodb://[username:password]host1[:po…...

JDBC简单的示例

JDBC 编程步骤 加载驱动程序&#xff1a; Class.forName(driverClass) //加载MySql驱动 Class.forName("com.mysql.jdbc.Driver") //加载Oracle驱动 Class.forName("oracle.jdbc.driver.OracleDriver")获得数据库连接&#xff1a; DriverManager.getCon…...

Spring架构篇--2.3 远程通信基础--IO多路复用select,poll,epoll模型

前言&#xff1a;对于传统的BIO&#xff08;同步阻塞&#xff09;模型&#xff0c;当有客户端连接达到服务端&#xff0c;服务端在对改连接进行连接建立&#xff0c;和数据传输过程中&#xff0c;是无法响应其他客户端的&#xff0c;只有当服务端完成对一个客户端处理后&#x…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...