C++ 虚继承
C++棱形继承
在 C++ 中,在使用 多继承 时,如果发生了如果类 A 派生出类 B 和类 C,类 D 继承自类 B 和类 C,这时候就发生了菱形继承。
如果发生了菱形继承,这个时候类 A 中的 成员变量 和 成员函数 继承到类 D 中变成了两份
一份来自 A–>B–>D 这条路径,另一份来自 A–>C–>D 这条路径。如下图所示:

在一个派生类中保留间接基类的多份同名成员,虽然可以在不同的成员变量中分别存放不同的数据,但大多数情况下这是多余的:因为保留多份成员变量不仅占用较多的存储空间,还容易产生命名冲突
假如类 A 有一个成员变量 a,那么在类 D 中直接访问 a 就会产生歧义,编译器不知道它究竟来自 A -->B–>D 这条路径,还是来自 A–>C–>D 这条路径
为了解决菱形继承出现的数据冗余的问题,C++ 提出了虚继承,虚继承使得派生类中只保留一份间接基类的成员
C++虚继承
虚继承的目的是让某个类做出声明,承诺愿意共享它的基类
其中,这个被共享的基类就称为虚基类(Virtual Base Class),菱形继承中的顶层类 就是一个虚基类
在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员
虚继承关系,如下图所示:

观察这个新的继承体系,我们会发现虚继承的一个不太直观的特征:
必须在虚派生的真实需求出现前就已经完成虚派生的操作。在上图中,当定义 D 类时才出现了对虚派生的需求,但是如果 B 类和 C 类不是从 A 类虚派生得到的,那么 D 类还是会保留 A 类的两份成员。
换个角度讲,虚派生只影响从指定了虚基类的派生类中进一步派生出来的类,它不会影响派生类本身。
在实际开发中,位于中间层次的基类将其继承声明为虚继承一般不会带来什么问题。通常情况下,使用虚继承的类层次是由一个人或者一个项目组一次性设计完成的。对于一个独立开发的类来说,很少需要基类中的某一个类是虚基类,况且新类的开发者也无法改变已经存在的类体系。
C++ 标准库中的 iostream 类就是一个虚继承的实际应用案例。iostream 从 istream 和 ostream 直接继承而来,而 istream 和 ostream 又都继承自一个共同的名为 base_ios 的类,是典型的菱形继承。此时 istream 和 ostream 必须采用虚继承,否则将导致 iostream 类中保留两份 base_ios 类的成员。
iostream 继承体系如下图:

使用案例:
#include <iostream>
using namespace std;
// 间接基类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()
{cout << "嗨客网(www.haicoder.net)\n" << endl;D d;return 0;
}
C++虚继承构造函数
普通的 继承 时,我们可以在子类直接显式的调用父类的 构造函数,在 虚继承 中,虚基类是由最终的派生类初始化的。
也就是说,最终派生类的构造函数必须要调用虚基类的构造函数
对最终的派生类来说,虚基类是间接基类,而不是直接基类。这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。
相关文章:
C++ 虚继承
C棱形继承 在 C 中,在使用 多继承 时,如果发生了如果类 A 派生出类 B 和类 C,类 D 继承自类 B 和类 C,这时候就发生了菱形继承。 如果发生了菱形继承,这个时候类 A 中的 成员变量 和 成员函数 继承到类 D 中变成了两…...
git commit用法
git commit 是 Git 版本控制系统中的一个命令,用于将更改提交到本地存储库。以下是 git commit 的一些常见用法和选项: 基本用法: git commit -m "提交信息"使用 -m 选项可以直接在命令行中添加提交信息。 提交所有更改: git commit -a -m &q…...
【LeetCode】543.二叉树的直径
题目 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1: 输入:root [1,2,3,4,5]…...
TypeScript教程(五)条件语句,循环,函数
一、条件语句 条件语句基于不同的条件来执行不同的动作 1.if语句:只有当指定条件为true时,使用该语句来执行代码 2.if...else语句:当条件为true时执行代码,当条件为else时执行其他代码 3.if...else if...else语句:…...
vue使用jsplumb 流程图
安装jsPlumb库:在Vue项目中使用npm或yarn安装jsPlumb库。 npm install jsplumb 创建一个Vue组件:创建一个Vue组件来容纳jsPlumb的功能和呈现。 <template><div style"margin: 20px"><div style"margin: 20px">&l…...
【BASH】回顾与知识点梳理(二十八)
【BASH】回顾与知识点梳理 二十八 二十八. 例行性工作排程(crontab)28.1 什么是例行性工作排程Linux 工作排程的种类: at, cronCentOS Linux 系统上常见的例行性工作 28.2 仅执行一次的工作排程atd 的启动at 的运作方式实际运作单一工作排程at 工作的管理batch&…...
LangChain源码逐行解密之系统(二)
LangChain源码逐行解密之系统 20.2 serapi.py源码逐行剖析 我们可以看一下Google查询的例子,在LangChain中有多种实现的方式。 如图20-5所示,在utilities的serpapi.py代码文件中实现了SerpAPIWrapper。 图20- 5 utilities的serpapi.py的SerpAPIWrapper 在langchain目录的se…...
QT的设计器介绍
设计器介绍 Qt制作 UI 界面,一般可以通过UI制作工具QtDesigner和纯代码编写两种方式来实现。纯代码实现暂时在这里不阐述了在后续布局章节详细说明,QtDesigner已经继承到开发环境中,在工程中直接双击ui文件就可以直接在QtDesigner设计器中打…...
[LitCTF 2023]Ping
因为直接ping会有弹窗。这里在火狐f12,然后f1选禁用javascript,然后ping 然后输入127.0.0.1;cat /flag 得到flag, 查看其他大佬的wp ,这里还可以抓包。但是不知道为什么我这里的burp 用不了...
Spring Cloud面试突击班1
Spring Cloud面试突击班1 1.Spring Cloud 中有哪些组件,整个项目架构中我们的重点又有哪些? Spring Cloud 是一套基于Spring Boot的微服务解决方案。 Spring Cloud生态在国内主流的分为两套,一套是以奈飞开源的Spring Cloud Netfilx 20%&a…...
线上售楼vr全景看房成为企业数字化营销工具
在房地产业中,VR全景拍摄为买家提供了虚拟看房的全新体验。买家可以通过相关设备,远程参观各个楼盘的样板间和实景,感受房屋的空间布局和环境氛围,极大地提高了购房决策的准确性。对于房地产开发商和中介机构来说,VR全…...
“深入探索JVM内部机制:解密Java虚拟机原理“
标题:深入探索JVM内部机制:解密Java虚拟机原理 摘要:本文将深入探索Java虚拟机(JVM)的内部机制,揭示其工作原理和关键组成部分,包括类加载、内存管理、垃圾回收、即时编译和运行时数据区域等。…...
最长 上升子序列
大家好 我是寸铁 希望这篇题解对你有用,麻烦动动手指点个赞或关注,感谢您的关注 不清楚蓝桥杯考什么的点点下方👇 考点秘籍 想背纯享模版的伙伴们点点下方👇 蓝桥杯省一你一定不能错过的模板大全(第一期) 蓝桥杯省一你一定不…...
Nginx的介绍
本资料转载于传智教育-解锁你的IT职业薪未来,仅用于学习和讨论,如有侵权请联系 视频地址:04-Nginx的优点_哔哩哔哩_bilibili 资源文档:链接:https://pan.baidu.com/s/1RlFl92FdxRUqc858JSxPSQ 提取码:12…...
[杂项]奥特曼系列影视列表大全
1966年:《奥特曼》「初代奥特曼」 1967年:《奥特赛文》 1971年:《归来的奥特曼》「杰克奥特曼」 1972年:《艾斯奥特曼》 1973年:《泰罗奥特曼》 1974年:《雷欧奥特曼》 1979年动画版:《乔尼亚斯…...
java代码日记--java 基础语法
java代码日记 在线运行 本地运行环境配置 Java 实例 实战 java8 Java 基础语法 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。 下面简要介绍下类、对象、方法和实例变量的概念。 对象:对象是类的一个实例&…...
Spring中的IOC与DI-细胞内物质与传递
对IOC的认识 Spring Inversion of Control简称Spring IOC,是一种设计原则,通过它可以实现对象之间的解耦。通过Spring DI(Dependency Injection)依赖注入实现对象生命周期管理,为开发者提供对象创建、使用方式。 Spring中的Bean 在Spring框…...
【探索Linux】—— 强大的命令行工具 P.5(yum工具、git 命令行提交代码)
阅读导航 前言一、软件包管理器 yum1.yum的概念yum的基本指令使用例子 二、git 命令行提交代码总结温馨提示 前言 前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C的一些知识,也学习了一些Linux的基本操作,也了…...
jdbc 使用rewriteBatchedStatements=true后,报错
jdbc 使用rewriteBatchedStatementstrue后,报错了 rewriteBatchedStatementstrue解释 rewriteBatchedStatementstrue是一个配置选项,它影响MySQL JDBC驱动程序的行为。JDBC是Java数据库连接的标准。当你使用Java程序连接MySQL数据库时,你需要…...
第G1周:生成对抗网络(GAN)入门
🍨 本文为[🔗365天深度学习训练营]内部限免文章(版权归 *K同学啊* 所有) 🍖 作者:[K同学啊] 一、理论基础 生成对抗网络(Generative Adversarial Networks, GAN)是近年来深度学习领域…...
深入解析Cache工作原理与多核一致性机制
深入理解Cache工作原理与技术实现1. 计算机体系中的Cache基础1.1 Cache存在的必要性现代计算机系统中,处理器性能与存储器访问性能之间存在显著差距。从历史发展数据来看,CPU计算性能每18个月翻一番(遵循摩尔定律),而D…...
零基础玩转OpenClaw:Qwen3-32B-Chat镜像云端体验指南
零基础玩转OpenClaw:Qwen3-32B-Chat镜像云端体验指南 1. 为什么选择云端体验OpenClaw? 第一次听说OpenClaw时,我正被各种本地部署的依赖项折磨得焦头烂额。作为一个习惯在MacBook上写代码的开发者,光是配置CUDA环境就让我望而却…...
2026年03月CCF-GESP编程能力等级认证Scratch图形化编程二级真题解析
本文收录于《Scratch等级认证CCF-GESP图形化真题解析》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 3 分,共 30 分) 第 1 题 在 2026 年春晚的《武 BOT》节目中,一群机器人表演空翻:它们落地后晃一下又能站稳,还会移动保持队形整齐。如果…...
trt 动态batchsize优化:trtexec工具ONNX转engine实战指南
1. 为什么需要动态batchsize优化 在实际的AI模型部署中,我们经常会遇到输入数据量不固定的情况。比如视频分析场景,可能同时有1路或8路视频需要实时处理;又比如在线服务,请求量会随时间波动。这时候如果使用固定batchsize…...
从‘它怎么又挂了’到‘服务稳如狗’:我是如何用Prometheus+Grafana给自家小项目做监控的
从零搭建轻量级服务监控:PrometheusGrafana实战指南 凌晨三点,手机突然响起刺耳的警报声——这已经是本周第三次被线上服务宕机惊醒。作为独立开发者或小团队,我们往往身兼数职,既要写代码又要维护基础设施。服务崩溃时才发现问题…...
R语言新手必看:clusterProfiler功能富集分析从安装到实战(附常见报错解决方案)
R语言实战:clusterProfiler功能富集分析全流程指南 第一次接触功能富集分析时,我被那些密密麻麻的基因列表和复杂的生物学术语搞得晕头转向。直到发现了clusterProfiler这个神器,它就像生物信息学分析中的瑞士军刀,把复杂的富集过…...
all-MiniLM-L6-v2实战教程:用Python快速实现文本聚类分析
all-MiniLM-L6-v2实战教程:用Python快速实现文本聚类分析 1. 引言:为什么选择all-MiniLM-L6-v2 文本聚类是自然语言处理中的基础任务,它能帮助我们发现海量文本中的隐藏模式。传统方法如TF-IDF或词袋模型往往难以捕捉语义信息,而…...
Debian12下Docker国内镜像加速全攻略:以腾讯云为例快速部署WordPress
Debian12下Docker国内镜像加速全攻略:以腾讯云为例快速部署WordPress 在Debian12系统中使用Docker时,国内用户常遇到镜像下载速度慢的问题。本文将详细介绍如何配置国内镜像源加速Docker,并以腾讯云为例,快速部署WordPress环境。…...
R语言新手必看:如何用pkgbuild和Sys.which检查并安装Rtools(附绑定教程)
R语言开发环境配置全指南:从Rtools安装到编译环境搭建 刚接触R语言的开发者,在尝试从源代码编译安装某些扩展包时,常常会遇到"make not found"之类的错误提示。这通常意味着系统缺少必要的编译工具链。本文将详细介绍如何在Windows…...
管人对账累垮人?巨有科技智慧市集系统一招减负
从城市商圈到景区古镇,从乡村田园到文创园区,各类市集遍地开花,但管理难题始终是制约行业发展的最大瓶颈。人工登记杂乱、对账结算繁琐、现场管控滞后、数据完全空白,一场中型市集就要耗费大量人力物力,大型市集更是纠…...
