【C++】继承 ⑫ ( 继承的二义性 | virtual 虚继承 )
文章目录
- 一、继承的二义性
- 1、场景说明 - 继承的二义性
- 2、继承中的二义性报错
- 3、完整代码示例
- 二、virtual 虚继承
- 1、虚继承引入
- 2、虚继承语法
- 3、代码示例 - 虚继承
一、继承的二义性
1、场景说明 - 继承的二义性
A 类 是 父类 ,
B 类 和 C 类 继承 A 类 , 是 子类 ,
D 类 多继承 B 类 和 C 类 , 是 孙子类 ;

假如 A 类中有 成员变量 x ,
则 子类 B 类 和 C 类 都会继承该 成员变量 x ,
D 类 多继承 B 类 和 C 类 , 会 分别从 B 和 C 各自 继承一个 成员变量 x ;
D 类中 , 从 B , C 两个父类中继承自 爷爷类 A 的成员变量 , 会出现二义性 ;
代码如下 :
#include "iostream"
using namespace std;class A {
public:int x;
};// 子类 B 继承了父类 A 的 x 成员
class B : public A {
public:int y;
};// 子类 C 继承了父类 A 的 x 成员
class C : public A {
public:int z;
};// D 多继承 B 和 C
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:int k;
};
2、继承中的二义性报错
如果强行使用 对象.x 访问继承自 A , 会报错 error C2385: 对“x”的访问不明确 ;
定义 D 类的对象 d , 如果访问 继承自 A 类的 x 成员 , 则会出现二义性 ;
// 定义 D 类对象 dD d;// 访问 继承自 A 类的 x 成员出现二义性// 报错 error C2385: 对“x”的访问不明确d.x = 40;
完整报错信息 :
1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>Test.cpp
1>Test.cpp(41,6): error C2385: 对“x”的访问不明确
1>Test.cpp(41,6): message : 可能是“x”(位于基“A”中)
1>Test.cpp(41,6): message : 也可能是“x”(位于基“A”中)
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
3、完整代码示例
代码示例 :
#include "iostream"
using namespace std;class A {
public:int x;
};// 子类 B 继承了父类 A 的 x 成员
class B : public A {
public:int y;
};// 子类 C 继承了父类 A 的 x 成员
class C : public A {
public:int z;
};// D 多继承 B 和 C
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:int k;
};int main() {// 定义 D 类对象 dD d;// 访问继承自 B 类的 y 成员d.y = 10;// 访问继承自 C 类的 z 成员d.z = 20;// 访问 D 类自己的成员 kd.k = 30;// 访问 继承自 A 类的 x 成员出现二义性// 报错 error C2385: 对“x”的访问不明确//d.x = 40;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
}
执行结果 :

二、virtual 虚继承
1、虚继承引入
在多继承中 , 如果一个类继承了多个含有相同基类的派生类 , 就会产生菱形继承结构 ;
这种情况下 , 可能会出现多个不同的基类实例 , 导致重复定义和二义性 ;
为了应对上述 继承的二义性 问题 ,
C++ 语言 使用 " 虚继承 " 解决 继承中的 二义性问题 ;
C++ 中的 " 虚继承 " 是一种解决 多继承 带来的 菱形问题(diamond problem)的技术 ;
虚继承的目的是 确保每个基类只被继承一次 , 从而避免 重复定义 和 二义性等问题 ;
虚继承 通过在 派生类 中使用关键字 virtual 来指示基类应该被虚继承 , 虚继承确保了每个基类只被继承一次 , 从而避免了重复定义和二义性 ;
在 C++ 中,使用虚继承的语法是在基类列表中使用 virtual 关键字 ;
2、虚继承语法
虚继承语法 : 在 继承的 访问限定符 之前 , 添加 virtual 关键字 , 将该继承行为定义为 " 虚继承 " ;
class 子类类名 : virtual 访问限定符 父类类名
{// 子类内容
}
下面的 B 类 和 C 类 , 就是 虚继承 类 A ;
class A {
public:int x;
};// 子类 B 继承了父类 A 的 x 成员
class B : virtual public A {
public:int y;
};// 子类 C 继承了父类 A 的 x 成员
class C : virtual public A {
public:int z;
};
3、代码示例 - 虚继承
代码示例 :
#include "iostream"
using namespace std;class A {
public:int x;
};// 子类 B 继承了父类 A 的 x 成员
class B : virtual public A {
public:int y;
};// 子类 C 继承了父类 A 的 x 成员
class C : virtual public A {
public:int z;
};// D 多继承 B 和 C
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:int k;
};int main() {// 定义 D 类对象 dD d;// 访问继承自 B 类的 y 成员d.y = 10;// 访问继承自 C 类的 z 成员d.z = 20;// 访问 D 类自己的成员 kd.k = 30;// 访问 继承自 A 类的 x 成员出现二义性// 报错 error C2385: 对“x”的访问不明确// 使用 virtual 虚继承后 , 不会报错d.x = 40;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
}
执行结果 :

相关文章:
【C++】继承 ⑫ ( 继承的二义性 | virtual 虚继承 )
文章目录 一、继承的二义性1、场景说明 - 继承的二义性2、继承中的二义性报错3、完整代码示例 二、virtual 虚继承1、虚继承引入2、虚继承语法3、代码示例 - 虚继承 一、继承的二义性 1、场景说明 - 继承的二义性 A 类 是 父类 , B 类 和 C 类 继承 A 类 , 是 子类 , D 类 多…...
Linux网络流量监控iftop
在 Linux 系统下即时监控服务器的网络带宽使用情况,有很多工具,比如 iptraf、nethogs 等等,但是推荐使用小巧但功能很强大的 iftop 工具【官网:http://www.ex-parrot.com/~pdw/iftop/】。iftop 是 Linux 系统一个免费的网卡实时流…...
【虚幻引擎UE】UE4/UE5 基于2D屏幕坐标获取场景3D坐标 射线检测(蓝图/C++)
UE4/UE5 基于2D屏幕坐标获取场景3D坐标 一、射线检测1)定义1)射线与3D场景中的物体交互的流程2)射线检测蓝图函数3)蓝图实现根据鼠标点击位置获取场景中的坐标值4)根据相机中心点获取场景中的坐标值5)射线检…...
【OpenHarmony】系统编译环境搭建笔记
0、安装WSL 一定要安装WSL 2否则编译慢到怀疑人生。 1、将WSL从C盘迁移到其他盘 2、安装编译依赖库 按照上述流程,安装会提示一些错误,直接使用如下命令: sudo apt-get update && sudo apt-get install binutils binutils-dev g…...
深入理解JVM虚拟机第十二篇:JVM中的线程说明
文章目录 一:线程说明 1:线程概述 2:后台虚拟机主要线程 (一):虚拟机线程...
synchronized 、ReentrantLock
synchronized 和 ReentrantLock 都是用于实现多线程同步的机制: 锁的获取方式: synchronized 是内置的 Java 关键字,它通过对象的内置监视器来获取锁。每个对象都有一个关联的监视器,只有一个线程可以获得对象的监视器,其他线程必须等待。ReentrantLock 是一个类,它提供了…...
用VSCODE启动Java项目
下载插件 推荐下载插件 启动 在vscode中打开项目或将项目拖进vscode,等进度条加载完成即成启动项目...
最简单的修改linux系统上Docker的镜像源
前言 是不是从docker上下载镜像总是很慢 我有两个物理服务器,两个都在本地不能访问国际网络,那只能使用国内网络,就是下载docker镜像太慢了,慢的我心情都不好了,所以就出了这篇文章用来解决docker下载慢的问题 正文 1.首先你得下载好docker,在Linux上,下载Docker的命令是下面这…...
layui移除(删除)table表格的一行
表格里添加删除按钮: , {field: wealth, width: 150, title: 操作, align: center, fixed: right,templet: function (item) {return <a style"margin:0px 5px; color:red; cursor: pointer;" lay-event"delete" id"DeleteTr" >…...
67 跳跃游戏 II
跳跃游戏 II 题解1 贪心1 正向题解2 贪心2 反向题解3 DP 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 &…...
客户中心模拟(Queue and A, ACM/ICPC World Finals 2000, UVa822)rust解法
你的任务是模拟一个客户中心运作情况。客服请求一共有n(1≤n≤20)种主题,每种主题用5个整数描述:tid, num, t0, t, dt,其中tid为主题的唯一标识符,num为该主题的请求个数,t0为第一个请求的时刻&…...
方案聚焦:高可用的F5分布式云DNS负载均衡
DNS是实现互联网的主要技术之一。它也是网络基础设施的重要组成部分,DNS管理一个分布式和冗余的架构,确保高可用性和高质量的用户响应时间,因此拥有一个可用的、智能的、安全和可扩展的DNS基础设施是至关重要的。然而DNS没有真正的能力来分配…...
大数据性能测试方案-V1.0
XXX大数据平台 性能测试方案 [V1-1.0] 拟 制 人: 审 核 人: 批 准 人: [xxxx年xx月xx日]...
Kafak - 单机/集群快速安装指北(3.x版本)
文章目录 官方下载地址上传安装包解压安装包到指定目录修改解压包名为kafka修改config目录下的配置文件server.propertie配置环境变量其他机器同上 - 修改配置文件中的brokerid启动集群停止Kraft 方式部署集群----(不使用zookeeper) 官方下载地址 http://kafka.apache.org/dow…...
互联网Java工程师面试题·Spring篇·第五弹
目录 1、什么是 spring? 2、使用 Spring 框架的好处是什么? 3、Spring 由哪些模块组成? 4、核心容器(应用上下文) 模块。 5、BeanFactory – BeanFactory 实现举例。 6、XMLBeanFactory 7、解释 AOP 模块 8、解释 JDBC 抽象和 DAO 模块。 9、…...
XTU-OJ 1221-Binary
题目描述 给你一个非负整数n(0≤n≤232-1),求其二进制里面最长连续1数码的长度。 比如,7的二进制为111,所以最长连续1数码的长度为3;13的二进制为1101,所以最长连续1数码的长度为2. 输入 第一行是一个整数K(K≤20000),表示样例的个…...
Chromium源码由浅入深(三)
接前一篇文章:Chromium源码由浅入深(二) 上一回说到了关键的“钥匙”:browserBridge.gpuInfo,本文就针对其进行深入探究。 先来看前半部分,browserBridge。 在content/browser/resources/gpu/gpu_interna…...
如何集成验证码短信API到你的应用程序
引言 当你需要为你的应用程序增加安全性和用户验证功能时,集成验证码短信API是一个明智的选择。验证码短信API可以帮助你轻松实现用户验证、密码重置和账户恢复等功能,提高用户体验并增强应用程序的安全性。本文将介绍如何将验证码短信API集成到你的应用…...
Linux- 由映射文件I/O问题引出的SIGBUS 空洞文件(Sparse File)
SIGBUS SIGBUS是一个在Unix-like操作系统中的信号,它通常表示非法访问内存,而这种非法访问的原因与常见的SIGSEGV(段错误)有所不同。以下是可能导致SIGBUS的常见情况: 未对齐的内存访问:某些硬件平台要求数…...
代码随想录图论 第二天 | 695. 岛屿的最大面积 1020. 飞地的数量
代码随想录图论 第二天 | 695. 岛屿的最大面积 1020. 飞地的数量 一、695. 岛屿的最大面积 题目链接:https://leetcode.cn/problems/max-area-of-island/ 思路:典型的遍历模板题,我采用深度优先,每块岛屿递归遍历的时候计数&…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
