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

C++:菱形继承与虚继承

看下面这个示例代码

class A{
public:
int num=10;
A(){cout<<"A构造"<<endl;}
virtual void fun(){cout<<"A虚函数"<<endl;}
};class B:public A{
public:
B(){cout<<"B构造"<<endl;}
void fun(){cout<<"B虚函数"<<endl;}
};class C:public A{
public:
C(){cout<<"C构造"<<endl;}
void fun(){cout<<"C虚函数"<<endl;}
};class D:public C,public B{
public:
D(){cout<<"D构造"<<endl;}
void fun(){cout<<"D虚函数"<<num<<endl;}
};

这段代码你会发现这段代码编译不通过,因为D类的虚函数在访问num时不知道访问哪个,将这个虚函数里面的内容清空然后执行会得到以下结果:
在这里插入图片描述

可以看到D多次继承了同一个基类,这样就造成了构造D时构造了多个A,问题本身没有什么影响但是如果D需要访问A中的东西时就会有两个渠道,通过B或者C,这时候加上作用域的话就可以运行了,但是这样太麻烦了,而且对共同的基类A真的没必要构造两次,为了处理这种情况引入了虚继承的概念。
之前介绍过虚函数,虚继承和它类似

  • 发生虚继承的时候就会产生一个虚基表和相应的虚基表指针
  • 虚基表是静态的,这点和虚函数表差不多
  • 发生虚继承后对任意类只会创建一次
  • 虚基表存储虚基表指针到其基类的偏移量
  • 一个类只会有一个虚基表,但是可以有多个虚基表指针

这些概念后面梳理,现在先看修改后的代码

class A{
public:
int num=10;
A(){cout<<"A构造"<<endl;}
virtual void fun(){cout<<"A虚函数"<<endl;}
};
class B:virtual public A{
public:
B(){cout<<"B构造"<<endl;}
void fun(){cout<<"B虚函数"<<endl;}
};
class C:virtual public A{
public:
C(){cout<<"C构造"<<endl;}
void fun(){cout<<"C虚函数"<<endl;}
};
class D:virtual public C,virtual public B{
public:
D(){cout<<"D构造"<<endl;}
void fun(){cout<<"D虚函数"<<num<<endl;}
};

看看执行结果
在这里插入图片描述
可以看出问题被解决了,接下来看它在内存中的分布
在vs开发者命令行模式下输入下面的指令即可

cl /d1 reportSingleClassLayoutXXX 文件名.cpp

xxx替换为自己的类名,我这里是D

在这里插入图片描述
可以看到类的结构还是很清晰的,每个使用虚继承的类头部都有一个虚基表指针,同时虚函数表指针不再出现在头部,不需要过多解释自己看吧
在这里插入图片描述
虚继承通过减少基类的重复创建解决了多次继承同一基类造成的二义性问题,借助虚基表完成了基类的定位,可以说很是牛皮,但是缺点也很明显它破坏了类中的原有布局,它使类中的内存分布情况程序多样化,现在虚函数表指针可能有多个甚至位置也会按照继承的顺序而改变,内存的分布依赖于代码书写,所以说要慎用,虽然我们不需要过多关注内存,但是对性能的影响却是真实存在的。

相关文章:

C++:菱形继承与虚继承

看下面这个示例代码 class A{ public: int num10; A(){cout<<"A构造"<<endl;} virtual void fun(){cout<<"A虚函数"<<endl;} };class B:public A{ public: B(){cout<<"B构造"<<endl;} void fun(){cout<…...

贡献法:USACO 2021 December Contest Bronze:孤独的照片

Farmer John 最近购入了 N 头新的奶牛&#xff0c;每头奶牛的品种是更赛牛&#xff08;Guernsey&#xff09;或荷斯坦牛&#xff08;Holstein&#xff09;之一。 奶牛目前排成一排&#xff0c;Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。 然而&#xff0c;他…...

Java实现简单的通讯录

每日一言 泪眼问花花不语&#xff0c;乱红飞过秋千去。 —欧阳修- 简单的通讯录实现&#xff0c;跟写Java实现图书管理系统差不多&#xff0c;用到的知识也差不多&#xff0c;就当个小练习&#xff0c;练习一下写Java程序的手感。 Java实现图书管理系统 关于通讯录的代码都写…...

服务器数据恢复—raid5热备盘上线同步数据失败的如何恢复数据

服务器数据恢复环境&故障&分析&#xff1a; 一台存储上有一组由多块硬盘组建的raid5阵列&#xff0c;该raid5阵列中的一块硬盘掉线&#xff0c;热备盘自动上线同步数据的过程中&#xff0c;raid阵列中又有一块硬盘掉线&#xff0c;热备盘的数据同步被中断&#xff0c;r…...

探索C语言中的循环结构

循环结构是程序设计中一种重要的控制结构&#xff0c;它允许程序重复执行特定的代码块&#xff0c;直到满足某个条件为止。在C语言中&#xff0c;循环结构有多种形式&#xff0c;如for循环、while循环和do-while循环。本文将介绍C语言中的循环结构&#xff0c;并讨论它们的用法…...

数学建模-估计出租车的总数

文章目录 1、随机抽取的号码在总体的排序 1、随机抽取的号码在总体的排序 10个号码从小到大重新排列 [ x 0 , x ] [x_0, x] [x0​,x] 区间内全部整数值 ~ 总体 x 1 , x 2 , … , x 10 总体的一个样本 x_1, x_2, … , x_{10} ~ 总体的一个样本 x1​,x2​,…,x10​ 总体的一个样…...

设计模式在芯片验证中的应用——装饰器

一、装饰器模式 装饰器模式(Decorator)是一种结构化软件设计模式&#xff0c;它提供了一种通过向类对象添加行为来修改类对象的方法&#xff0c;而不会影响同一类的其它对象行为。该模式允许在不修改抽象类的情况下添加类功能。它从本质上允许基类代码对不可预见的修改具有前瞻…...

Python 查找并高亮PDF中的指定文本

在处理大量PDF文档时&#xff0c;有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…...

LEETCODE LCS 03. 主题空间

题目描述如上&#xff0c;这个题主要运用了DFS的思想&#xff0c;同时走过的路径标记为6&#xff0c;即可在后续的遍历中过滤掉重复的元素&#xff0c;其他则类似边界条件的判断和题目条件的判断&#xff0c;求最大值&#xff0c;只需要一次遍历中累加对比每一次得即可。 模板&…...

【Spring Boot 源码学习】深入应用上下文初始化器实现

《Spring Boot 源码学习系列》 深入应用上下文初始化器实现 一、引言二、往期内容三、主要内容3.1 spring-boot 子模块中内置的实现类3.1.1 ConfigurationWarningsApplicationContextInitializer3.1.2 ContextIdApplicationContextInitializer3.1.3 DelegatingApplicationConte…...

【Docker】一文趣谈Docker

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 …...

代码随想录day19(2)二叉树:二叉树的最大深度(leetcode104)

题目要求&#xff1a;求出二叉树的最大深度 思路&#xff1a;首先要区分二叉树的高度与深度。二叉树的高度是任一结点到叶子结点的距离&#xff0c;而二叉树的深度指的是任一节点到根节点的距离&#xff08;从1开始&#xff09;。所以求高度使用后序遍历&#xff08;从下往上&…...

Lua中文语言编程源码-第五节,更改lcorolib.c协程库函数, 使Lua加载中文库关键词(与所有的基础库相关)

源码已经更新在CSDN的码库里&#xff1a; git clone https://gitcode.com/funsion/CLua.git 在src文件夹下的lcorolib.c协程库函数&#xff0c;Coroutine Library&#xff1a;表明这个C源文件实现了Lua的协程库&#xff08;Coroutine Library&#xff09;&#xff0c;即提供了…...

Docker学习之数据管理(超详解析)

Docker存储资源类型&#xff1a; 用户在使用 Docker 的过程中&#xff0c;势必需要查看容器内应用产生的数据&#xff0c;或者需要将容器内数据进行备份&#xff0c;甚至多个容器之间进行数据共享&#xff0c;这必然会涉及到容器的数据管理&#xff1a; &#xff08;1&#xff…...

FDTD液晶折射率各项异性表示方法

由于FDTD的数据都是沿坐标轴的&#xff0c;各向异性材料的参数也需要根据坐标轴来输入。 首先要了解坐标变换。 坐标变换 这里以二维坐标变化为例。 矢量下我们可以发现OP可在两个坐标系下分别表示 接下来将两个坐标相互关联&#xff0c;这里以Xb举例&#xff0c;Yb同理 注…...

RoketMQ主从搭建

vim /etc/hosts# IP与域名映射&#xff0c;端口看自己的#nameserver 192.168.126.132 rocketmq-nameserver1 192.168.126.133 rocketmq-nameserver2# 注意主从节点不在同一个主机上 #broker 192.168.126.132 rocketmq-master1 192.168.126.133 rocketmq-master2#broker 192.168…...

Linux网络瑞士军刀 nc(netcat)

1.命令简介 nc&#xff08;netcat&#xff09;是一个短小精悍、功能实用、简单可靠的网络工具&#xff0c;主要有如下作用&#xff1a; &#xff08;1&#xff09;端口侦听&#xff0c;nc 可以作为 server 以 TCP 或 UDP 方式侦听指定端口&#xff1b; &#xff08;2&#x…...

1.Spring入门

1.1 Spring简介 Spring是一个轻量级Java 企业级应用程序开发框架&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架&#xff0c;为开发Java应用程序提供全面的基础架构支持。 Spring Fra…...

【JavaEE Spring 项目】消息队列的设计

消息队列的设计 一、消息队列的背景知识二、需求分析核心概念⼀个⽣产者, ⼀个消费者N 个⽣产者, N 个消费者Broker Server 中的相关概念核⼼ API交换机类型 (Exchange Type)持久化⽹络通信消息应答 三、 模块划分四、 项⽬创建五、创建核心类创建 Exchange创建 MSGQUeue创建 B…...

SpringFramework学习笔记(Spring IoC,aop,tx)

SpringFramework 本篇笔记是基于尚硅谷学习资料的整理&#xff0c;涉及到其笔记的简化&#xff0c;补充&#xff0c;以及我在学习中遇到的与无法理解的问题及解决&#xff0c;如果想看完整及后续的笔记&#xff0c;可以去https://www.wolai.com/v5Kuct5ZtPeVBk4NBUGBWF查看官方…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...