C++ 多态之虚继承

news2024/10/6 10:33:04

什么是虚继承

C++支持多继承的形式,但若被继承的不同基类又同属与某一个接口类or基类的派生类,那么很容易产生经典的菱形继承问题,这样不可避免的带来了命名冲突,访问不明确的问题,如图所示:
在这里插入图片描述

虚继承解决的问题菱形继承是什么?

  1. 基类A派生出类B和类C
  2. 派生类D同时继承自类B和类C,这时候基类A中的成员变量、成员函数在类D中变成了两份
  3. 路径1:A–>B–>D;路径2:A–>C–>D

派生类中保留间接基类的多份成员,保留的成员分别存储在不同的直接基类下,虽然可以通过类+作用域的形式去访问修改,但这很容易产生bug,大多数情况下都是冗余的。

代码释义及原理分析

//base基类A
class A {
protected:
	int m_a;
};
//派生基类B
class B : public A {
protected:
	int m_b;
};
//派生基类C
class C : public A {
protected:
	int m_c;
};
//派生类D
class D : public B, public C {
public:
	void Set_a(int a) { 
		m_a    = a; //访问不明确
		C::m_a = a; //C中的a
		B::m_a = a;  //B 中的a
	}
private:
	int m_d;
};

这个问题在编译期就会报错,告知访问不明确,从D的内存布局上们也可以清楚的看到m_a变量会有两份,分别在Base Class B和Base Class C下面

在这里插入图片描述

虚继承

//base基类A
class A {
protected:
	int m_a;
};
//派生基类B
class B : virtual public A {
protected:
	int m_b;
};
//派生基类C
class C : virtual public A {
protected:
	int m_c;
};
//派生类D
class D : public B, public C {
public:
	void Set_a(int a) { 
		m_a    = a; //虚基类中的a
		C::m_a = a; //虚基类中的a
		B::m_a = a; //虚基类中的a
	}
private:
	int m_d;
};

只需要我们基类B和C的定义时,通过virtual public A 的方式进行虚继承,这样在内存布局上,类B或者C的内存布局就会添加一个虚基类指针,并指向虚基类表。
在这里插入图片描述

另外我们也可以通过编译器直接查看内存布局,发现和我们的分析完全一致,这样当我们需要访问m_a时都会最终通过虚基类表,找到唯一的一份变量。
在这里插入图片描述

虚继承的常见问题

  • 间接基类没有虚继承,直接基类进行虚继承,最终仍会保留多份间接基类
    在这里插入图片描述

  • 一个直接基类通过虚继承派生,另一个直接基类普通继承,也会保留两份间接基类,一份在直接继承的类中,另一份在虚基类中
    在这里插入图片描述

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

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

相关文章

【目标感知:IVIF:轻量级架构】

SELAFUSE: SEARCH A LIGHTWEIGHT ARCHITECTURE FOR TARGET-AWARE INFRARED AND VISIBLE IMAGE FUSION (SELAFUSE: 搜索轻量级架构以实现目标感知的红外和可见光图像融合) 尽管深度学习技术最近在红外和可见光图像融合方面表现出出色的性能,…

如何使用DNS加速你的浏览器访问速度?

不知道大家有没有遇到过这种情况, 我们访问用浏览器网页无法正常显示, 但是我们使用的QQ却能正常的打开? 这是因为 : 我们在登录QQ的时候是直接访问的腾讯的服务器, 在下载好的QQ客户端已经帮你配置好了所有的IP, 所有没有域名解析的操作, 所以可以正常的登录 解决办法如下…

c#入门-引用变量

引用变量 引用传递,是c#为了以更为安全的方式代替指针做出来的产物。 类似引用类型储存一个地址。但和引用类型不同的是,连对他本身的访问和修改都会转为对原值的访问和修改。 声明引用变量 引用变量在声明是,需要给类型前加上关键字ref。…

02.Ioc容器加载过程-Bean的生命周期深度剖析——四

BeanFactory:使用简单工厂,负责生产Bean FactoryBean:被他修饰的的类,成为特殊的类,调用getObgrct()得到最终的类。。。用于类的实现接口重写方法,从而扩展功能 IOC再总结: 实例化AnnotationCo…

【阅读笔记】《人月神话》思想提炼

文章目录前言1. 衡量工作量1.1. 单位1.2. 工作量与人月(人天)的关系1.2.1 忽略了沟通成本1.2.2 忽略了需求的特征2. 外科手术团队 —— 少部分人主导项目2.1. 执行方式2.2. 遵守的理念3. 警惕“遗留需求”4. 管理进度4.1 不要泄气4.2. 设定合适的里程碑并…

java项目_第170期ssm二手手机回收平台系统_ssm毕业设计_计算机毕业设计

java项目-第170期ssm二手手机回收平台系统-ssm毕业设计_计算机毕业设计 【源码请到下载专栏下载】 今天分享的项目是《ssm二手手机回收平台系统》 该项目分为2个角色,管理员和用户。 用户可以浏览前台,包含功能有: 首页、手机商城、新闻资讯、跳转到后台…

MRR和ICP

MRR和ICPMulti-Range Read优化ICP索引下推优化Multi-Range Read优化 MySQL5.6版本开始支持Multi-Range Read(MRR)优化。Multi-Range Read优化的目的就是为了减少磁盘的随机访问,并且将随机访问转化为较为顺序的数据访问,这对于IO…

每天进步一点点 -- pytorch学习:张量的介绍与创建

推荐查看的文档:机器视觉全栈|机器视觉教程|docsify|pytorch官方教程中文版|opencv-python官方教程中文版|open3D(0.15.1)官方教程中文版 Tensors个人理解为在GPU上工作的数组和矩阵,既然是数组和矩阵,那么里面也保存一些类型的内容&#xf…

圣天诺加密狗(HASP)破解

圣天诺加密狗&#xff08;HASP&#xff09;破解 一、编写测试程序 dll代码&#xff1a; #include "pch.h" #include<stdlib.h> BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) {switch (ul_reason_for_call){case D…

[附源码]计算机毕业设计和vue的茶文化交流平台的设计与实现Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

SVG 实现拟物态圆环进度条

前言 &#x1f44f;SVG 实现拟物态圆环进度条&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义一个圆角矩形作为父容器&#xff0c;背景色为–bg --bg: #edf1f5;<div class"container">&l…

lunar.js 基本使用学习笔记

文章目录lunar 基本使用学习笔记介绍基本使用部分文档 API 转载阳历相关的方法 APISolar 阳历阳历实例化阳历对象可以使用多种字符串输出方式&#xff1a;获取年、月、日儒略日获取星期判断是否闰年获取节日星座阳历日期推移&#xff08;可**跳过节假日、周六周日**&#xff09…

[附源码]Nodejs计算机毕业设计基于Java的医院预约挂号系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

SpringMVC的传参方式?

Request参数传递 1. Servlet传统API 2. Map/Model/ModelMap 作用域&#xff1a;request Map 是原生态的JDK类 Model/ModelMap 是Spring的类 除了来源不同&#xff0c;传递参数的功能都一致&#xff0c;用哪个都可以 Session参数传递 1. 传统方法HttpServletSession 2. …

[附源码]计算机毕业设计工程施工多层级管理架构Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Python列表(list)原址反序的4种方法

Python列表(list)原址反序的方法 (本文获得CSDN质量评分【x】)【学习的细节是欢悦的历程】Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… 自学并不是什么神秘的东西&a…

利用图文和代码深度解析操作系统OS内存泄漏检测实现原理与算法机制以及常见的泄露原因和解决方案

利用图文和代码深度解析操作系统OS内存泄漏检测实现原理与算法机制以及常见的泄露原因和解决方案。 计算机科学中,内存泄漏是一种资源泄漏。发生这种情况时,不再需要的内存未被释放,计算机程序以错误的方式管理内存分配。当对象存储在内存中但不能被运行代码无法访问时,也…

[附源码]Python计算机毕业设计殡仪馆管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

mha

MySQL MHA 报错处理 ​​​​​​- 走看看安装环境&#xff1a;CentOS 6.5 MySQL 5.7.22 MHA 0.56 1、找不到mysql 命令 Sat Mar 23 07:17:50 2019 - [info] Connecting tohttp://t.zoukankan.com/102x-p-10583959.html 实验 详解MHA搭建过程中的遇到的各种问题_时代广场的蟋蟀…

竞赛题-6257. 删除每行中的最大值

题目&#xff1a; 给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正整数组成。 执行下述操作&#xff0c;直到 grid 变为空矩阵&#xff1a; 从每一行删除值最大的元素。如果存在多个这样的值&#xff0c;删除其中任何一个。将删除元素中的最大值与答案相加。 注意 每…