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

C++虚基类详解

多继承(Multiple Inheritance)

是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。

注意: 多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如典型的是菱形继承。

A
B
C
D

基类 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 就是一个虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。

虚继承
虚继承
A
B
C
D

必须在虚派生的真实需求出现前就已经完成虚派生的操作
虚派生只影响从指定了虚基类的派生类中进一步派生出来的类,它不会影响派生类本身
理由: 在上图中,当定义 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)(四)

你可以的&#xff0c;去飞吧&#xff01; 同步代码和异步代码 回调函数地狱和 Promise 链式调用 回调函数地狱 缔造“回调地狱”↓ 制造里层回调错误&#xff0c;却在最外层接收错误→无法捕获 axios源码抛出异常&#xff08;未捕获&#xff09; <!DOCTYPE html> <ht…...

​TechSmith Camtasia 2024破解版功能介绍及使用教程

在现在的网络互联网时代&#xff0c;越来越多的人走上了自媒体的道路。有些自媒体人会自己在网络上录制精彩视频&#xff0c;也有一些人会将精彩、热门的电影剪辑出来再加上自己给它的配音&#xff0c;做成大家喜欢看的电影剪辑片段。相信不管大家是自己平时有独特的爱好也好、…...

【无线网络技术】——无线传输技术基础(学习笔记)

目录 &#x1f552; 1. 无线传输媒体&#x1f558; 1.1 地面微波&#x1f558; 1.2 卫星微波&#x1f558; 1.3 广播无线电波&#x1f558; 1.4 红外线&#x1f558; 1.5 光波 &#x1f552; 2. 天线&#x1f558; 2.1 辐射模式&#x1f558; 2.2 天线类型&#x1f564; 2.2.1 …...

【Liunx】部署WEB服务:Apache

【Liunx】部署WEB服务:Apache 概述Apache1.介绍2.Apache文件路径3.Apache详解(1)安装Apache(2)启动Apache(3)配置文件a.Apache主配置文件&#xff1a;vim /etc/httpd/conf/httpd.conf信息&#xff1a;b.基于主机头的虚拟主机 (4)开始演示&#xff1a;a.新建两个网站根目录b.分别…...

数字媒体技术基础之:常见图片文件格式

在数字图像处理和图形设计领域&#xff0c;了解不同的图片文件格式及其特点是至关重要的。每种格式都有其独特的用途和优势。以下介绍一些最常见的图片文件格式。 JPEG Joint Photographic Experts Group 扩展名&#xff1a;.jpg 或 .jpeg 特点&#xff1a; 1、有损压缩&#x…...

2023-2024-2 高级语言程序设计-二维数组

7-1 矩阵运算 给定一个nn的方阵&#xff0c;本题要求计算该矩阵除副对角线、最后一列和最后一行以外的所有元素之和。副对角线为从矩阵的右上角至左下角的连线。 输入格式: 输入第一行给出正整数n&#xff08;1<n≤10&#xff09;&#xff1b;随后n行&#xff0c;每行给出…...

【uniapp】确认弹出框,选择确定和取消

代码如下&#xff1a; <view style"display: flex; justify-content: space-around;"><button class"button" click"submit">t提交</button> </view>submit(){let thatthisuni.showModal({title: 提示&#xff1a;,con…...

阿里云容器镜像服务的运维总结

一、背景 容器镜像服务&#xff0c;作为一个可选付费产品&#xff0c;主要作用是存储docker的镜像仓库&#xff0c;供k8s拉取到Pod节点里。 你可以自己搭建一个harbor镜像仓库&#xff0c;在公司的开发环境下&#xff0c;将image推送到仓库&#xff1b;然后在生产k8s从仓库拉取…...

修炼k8s+flink+hdfs+dlink(七:flinkcdc)

一 &#xff1a;flinkcdc官网链接。 https://ververica.github.io/flink-cdc-connectors/release-2.1/content/about.html 二&#xff1a;在flink中添加jar包。 在flink lib目录下增加你所需要的包。 https://kdocs.cn/join/gv467qi?f101 邀请你加入共享群「工作使用重要工具…...

排查问题流程

1、问题定义和描述&#xff1a; 确定问题的性质、表现和影响。 收集和整理相关的问题描述和报告。 2、问题复现&#xff1a; 尝试在适当的环境中重现问题。 确定问题发生的条件、步骤和触发器。 3、问题分析&#xff1a; 收集和分析相关的日志、错误消息或警报。 使用适当的工…...

【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.字母异位词分组

字母异位词分组 题目及要求哈希算法在主函数内使用 题目及要求 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”…...

spark调优案例分享

做了一个Spark调优案例的分享 最近在整理了Spark相关的调优案例&#xff0c;并做了以下分享:spark调优案例 &#xff0c;注意是Mac Keynote...

阿里达摩院开源DAMO-YOLO

1.简介 DAMO-YOLO是一个兼顾速度与精度的目标检测框架&#xff0c;其效果超越了目前的一众YOLO系列方法&#xff0c;在实现SOTA的同时&#xff0c;保持了很高的推理速度。DAMO-YOLO是在YOLO框架基础上引入了一系列新技术&#xff0c;对整个检测框架进行了大幅的修改。具体包括…...

【异常检测小集】

目录 【2018 ICLR】DAGMM&#xff1a;Deep Autoencoding Gaussian Mixture Model for Unsupervised Anomaly Detection【2021 TNNLS】无名&#xff1a;Feature Encoding with AutoEncoders for Weakly-supervised Anomaly Detection 【2018 ICLR】DAGMM&#xff1a;Deep Autoen…...

Mybatis-Plus的IPage和Page

Mybatis-Plus 中的分页查询接口主要有两个&#xff1a;IPage 和 Page。 IPage 接口&#xff1a; IPage 是 Mybatis-Plus 中的分页结果集接口&#xff0c;它继承了 Mybatis 的 RowBounds 接口&#xff0c;提供了一系列的分页查询方法。该接口主要用于返回分页后的数据结果。 Pa…...

jupyter lab常用插件集合

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…...

centos 6.10 安装 boost 1.78.0

下载地址 找到对应的版本&#xff0c;下载源码&#xff0c;而不是二进制文件。 解压文件 cd boost_1_78_0 ./bootstrap.sh ./b2 install -perfix /usr/local/boost1.78.0/...

Vue 3.0 + vite + axios+PHP跨域问题的解决办法

最后一个Web项目&#xff0c;采用前后端分离。 前端&#xff1a;Vue 3.0 viteelement plus 后端&#xff1a;PHP 运行时前端和后端是两个程序&#xff0c;前端需要时才向后端请求数据。由于是两个程序&#xff0c;这就会出现跨域问题。 比如前端某个地方需要请求的接口如下…...

软件外包开发的开发文档

软件开发文档是一个重要的工具&#xff0c;用于记录和传达项目信息&#xff0c;帮助开发团队和利益相关者理解项目的各个方面。以下是一般性的软件开发文档编写格式&#xff0c;不同组织和项目可能有所不同&#xff0c;但这些通用准则可以帮助确保文档的清晰性和易读性&#xf…...

如何清理C盘文件

设置-系统-存储 在里面处理 搜索磁盘清理 然后选择系统文件&#xff0c;清理windows old等乱七八糟的东西 转移虚拟内存 关闭系统休眠功能 【管理员&#xff1a;命令提示符】窗口&#xff0c;输入命令&#xff1a;powercfg -h off&#xff0c;然后回车就可以关闭系统休眠…...

从测试的角度看待南航机票bug事件

事件描述 11月8日晚间&#xff0c;多名消费者反映南方航空多条成都进出港航线票价&#xff08;不含机建燃油费&#xff09;低至10元、20元、30元不等。上述超低价机票不仅在南方航空App可以购买&#xff0c;多家在线旅游平台也都能抢到。 11月9日&#xff0c;南航官方发布公告…...

通过 dump 虚拟机线程方法栈和堆内存来分析 Android 卡顿和 OOM 问题

作者&#xff1a;Tans5 Android 中的性能问题无非就是卡顿和 OOM&#xff0c;虽然总体就这两种&#xff0c;但是造成这两种性能问题的原因却是非常多&#xff0c;需要具体的原因具体分析&#xff0c;而且这是非常复杂的。本篇文章只是简单介绍如何找到造成这些问题的直接原因的…...

layui 框架的upload上传文件的data参数传到后端的方法

因为特殊性&#xff0c;upload.render初始化的data:{id:"sss"}不能传参到后台。 经过大量测试及参数网上方法&#xff0c;才发现&#xff0c;需要特殊处理&#xff1a; 1、如果直接给{id:"sss"}无效&#xff0c;但如果在before里&#xff0c;this.data.i…...

Java虚拟机的垃圾回收机制

Java虚拟机的垃圾回收机制 Java语言会对程序运行过程中产生的垃圾进行自动回收&#xff0c;不需要我们手动地写语句主动地对垃圾进行回收。 什么是垃圾&#xff1f; 在C语言中不再被使用的内存空间被称为垃圾&#xff0c;因为在C语言中如果我们使用到一些自定义类型的结构体&am…...

时间序列基础->数据标签、数据分割器、数据加载器的定义和讲解(零基础入门时间序列)

一、本文介绍 各位小伙伴好&#xff0c;最近在发时间序列的实战案例中总是有一些朋友问我时间序列中的部分对数据的操作是什么含义&#xff0c;我进行了挺多的介绍和讲解但是问的人越来越多&#xff0c;所以今天在这里单独发一篇文章来单独的讲一下时间序列中对数据的处理操作…...

【图论】最小生成树(python和cpp)

文章目录 一、声明二、简介三、代码C代码Python代码 一、声明 本帖持续更新中如有纰漏望指正&#xff01; 二、简介 &#xff08;a&#xff09;点云建立的k近邻图&#xff08;b&#xff09;k近邻图上建立的最小生成树 最小生成树 (Minimum Spanning Tree&#xff0c;简称 M…...