C++虚基类详解
多继承(Multiple Inheritance)
是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。
注意: 多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如典型的是菱形继承。
基类 A 派生出类 B 和类 C,子类 D 继承自类 B 和类 C。
这个时候类 A 中的成员变量和成员函数继承到类 D 中变成了两份,一份来自 A–>B–>D 这条路径,另一份来自 A–>C–>D 这条路径。
这样的问题在于,在D类中使用或者访问基类A中的成员函数、成员变量时会产生歧义。编译器不知道它是来着A–>B–>D,还是来自A–>C–>D这条路径。
//间接基类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 seta(int a){ m_a = a; } //命名冲突void setb(int b){ m_b = b; } //正确void setc(int c){ m_c = c; } //正确void setd(int d){ m_d = d; } //正确
private:int m_d;
};int main(){D d;return 0;
}
这段代码实现了上图所示的菱形继承,D类中,成员函数代码试图直接访问成员变量 m_a,结果发生了错误,因为类 B 和类 C 中都有成员变量 m_a(从 A 类继承而来),编译器不知道选用哪一个,所以产生了歧义。
为了消除歧义,可以在访问的时候给他标明是来自哪一个类的,比如以下代码
void seta(int a){ C::m_a = a; } //表明这个成员函数是通过 A-->C-->D 这条路径//或者这样
void seta(int a){ B::m_a = a; } //表明这个成员函数是通过 A-->B-->D 这条路径
虚继承(Virtual Inheritance)
为了解决多继承时的命名冲突和冗余数据问题,C++ 提出了虚继承,使得在派生类中只保留一份间接基类的成员。
在继承方式前面加上 virtual 关键字就是虚继承,比如以下代码中展示的
//间接基类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 seta(int a){ m_a = a; } //正确void setb(int b){ m_b = b; } //正确void setc(int c){ m_c = c; } //正确void setd(int d){ m_d = d; } //正确
private:int m_d;
};int main(){D d;return 0;
}
这段代码使用虚继承重新实现了上图所示的菱形继承,这样在派生类 D 中就只保留了一份成员变量 m_a,直接访问就不会再有歧义了。
虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。其中,这个被共享的基类就称为虚基类(Virtual Base Class),本例中的 A 就是一个虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。
必须在虚派生的真实需求出现前就已经完成虚派生的操作
虚派生只影响从指定了虚基类的派生类中进一步派生出来的类,它不会影响派生类本身
理由: 在上图中,当定义 D 类时才出现了对虚派生的需求,但是如果 B 类和 C 类不是从 A 类虚派生得到的,那么 D 类还是会保留 A 类的两份成员。
建议:能用单一继承解决的问题就不要使用多继承
相关文章:
C++虚基类详解
多继承(Multiple Inheritance) 是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。…...
Mac M2/M3 芯片环境配置以及常用软件安装-前端
最近换了台新 Mac,所有的配置和软件就重新安装下,顺便写个文章。 一、环境配置 1. 安装 Homebrew 安装 Homebrew【Mac 安装 Homebrew】 通过国内镜像安装会比较快 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Ho…...
Karmada更高效地实现故障转移
随着云原生技术的发展,其应用场景不断扩大。越来越多的企业开始将应用程序部署在 Kubernetes 集群中,随着 Kubernetes 集群规模的不断扩大,也带来了许多管理挑战,例如多集群间负载均衡、资源调度、故障转移等问题。为了解决这些问…...
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(四)
你可以的,去飞吧! 同步代码和异步代码 回调函数地狱和 Promise 链式调用 回调函数地狱 缔造“回调地狱”↓ 制造里层回调错误,却在最外层接收错误→无法捕获 axios源码抛出异常(未捕获) <!DOCTYPE html> <ht…...
TechSmith Camtasia 2024破解版功能介绍及使用教程
在现在的网络互联网时代,越来越多的人走上了自媒体的道路。有些自媒体人会自己在网络上录制精彩视频,也有一些人会将精彩、热门的电影剪辑出来再加上自己给它的配音,做成大家喜欢看的电影剪辑片段。相信不管大家是自己平时有独特的爱好也好、…...
【无线网络技术】——无线传输技术基础(学习笔记)
目录 🕒 1. 无线传输媒体🕘 1.1 地面微波🕘 1.2 卫星微波🕘 1.3 广播无线电波🕘 1.4 红外线🕘 1.5 光波 🕒 2. 天线🕘 2.1 辐射模式🕘 2.2 天线类型🕤 2.2.1 …...
【Liunx】部署WEB服务:Apache
【Liunx】部署WEB服务:Apache 概述Apache1.介绍2.Apache文件路径3.Apache详解(1)安装Apache(2)启动Apache(3)配置文件a.Apache主配置文件:vim /etc/httpd/conf/httpd.conf信息:b.基于主机头的虚拟主机 (4)开始演示:a.新建两个网站根目录b.分别…...
数字媒体技术基础之:常见图片文件格式
在数字图像处理和图形设计领域,了解不同的图片文件格式及其特点是至关重要的。每种格式都有其独特的用途和优势。以下介绍一些最常见的图片文件格式。 JPEG Joint Photographic Experts Group 扩展名:.jpg 或 .jpeg 特点: 1、有损压缩&#x…...
2023-2024-2 高级语言程序设计-二维数组
7-1 矩阵运算 给定一个nn的方阵,本题要求计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。副对角线为从矩阵的右上角至左下角的连线。 输入格式: 输入第一行给出正整数n(1<n≤10);随后n行,每行给出…...
【uniapp】确认弹出框,选择确定和取消
代码如下: <view style"display: flex; justify-content: space-around;"><button class"button" click"submit">t提交</button> </view>submit(){let thatthisuni.showModal({title: 提示:,con…...
阿里云容器镜像服务的运维总结
一、背景 容器镜像服务,作为一个可选付费产品,主要作用是存储docker的镜像仓库,供k8s拉取到Pod节点里。 你可以自己搭建一个harbor镜像仓库,在公司的开发环境下,将image推送到仓库;然后在生产k8s从仓库拉取…...
修炼k8s+flink+hdfs+dlink(七:flinkcdc)
一 :flinkcdc官网链接。 https://ververica.github.io/flink-cdc-connectors/release-2.1/content/about.html 二:在flink中添加jar包。 在flink lib目录下增加你所需要的包。 https://kdocs.cn/join/gv467qi?f101 邀请你加入共享群「工作使用重要工具…...
排查问题流程
1、问题定义和描述: 确定问题的性质、表现和影响。 收集和整理相关的问题描述和报告。 2、问题复现: 尝试在适当的环境中重现问题。 确定问题发生的条件、步骤和触发器。 3、问题分析: 收集和分析相关的日志、错误消息或警报。 使用适当的工…...
【nlp】2.2 传统RNN模型
传统RNN模型 1 传统RNN模型1.1 RNN结构分析1.2 使用Pytorch构建RNN模型1.3 传统RNN优缺点1 传统RNN模型 1.1 RNN结构分析 结构解释图: 内部结构分析: 我们把目光集中在中间的方块部分, 它的输入有两部分, 分别是h(t-1)以及x(t), 代表上一时间步的隐层输出, 以及此时间步的…...
C/C++---------------LeetCode第49.字母异位词分组
字母异位词分组 题目及要求哈希算法在主函数内使用 题目及要求 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”…...
spark调优案例分享
做了一个Spark调优案例的分享 最近在整理了Spark相关的调优案例,并做了以下分享:spark调优案例 ,注意是Mac Keynote...
阿里达摩院开源DAMO-YOLO
1.简介 DAMO-YOLO是一个兼顾速度与精度的目标检测框架,其效果超越了目前的一众YOLO系列方法,在实现SOTA的同时,保持了很高的推理速度。DAMO-YOLO是在YOLO框架基础上引入了一系列新技术,对整个检测框架进行了大幅的修改。具体包括…...
【异常检测小集】
目录 【2018 ICLR】DAGMM:Deep Autoencoding Gaussian Mixture Model for Unsupervised Anomaly Detection【2021 TNNLS】无名:Feature Encoding with AutoEncoders for Weakly-supervised Anomaly Detection 【2018 ICLR】DAGMM:Deep Autoen…...
Mybatis-Plus的IPage和Page
Mybatis-Plus 中的分页查询接口主要有两个:IPage 和 Page。 IPage 接口: IPage 是 Mybatis-Plus 中的分页结果集接口,它继承了 Mybatis 的 RowBounds 接口,提供了一系列的分页查询方法。该接口主要用于返回分页后的数据结果。 Pa…...
jupyter lab常用插件集合
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
