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

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 类就是一个虚继承的实际应用案例。iostreamistreamostream 直接继承而来,而 istreamostream 又都继承自一个共同的名为 base_ios 的类,是典型的菱形继承。此时 istreamostream 必须采用虚继承,否则将导致 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 中&#xff0c;在使用 多继承 时&#xff0c;如果发生了如果类 A 派生出类 B 和类 C&#xff0c;类 D 继承自类 B 和类 C&#xff0c;这时候就发生了菱形继承。 如果发生了菱形继承&#xff0c;这个时候类 A 中的 成员变量 和 成员函数 继承到类 D 中变成了两…...

git commit用法

git commit 是 Git 版本控制系统中的一个命令&#xff0c;用于将更改提交到本地存储库。以下是 git commit 的一些常见用法和选项&#xff1a; 基本用法: git commit -m "提交信息"使用 -m 选项可以直接在命令行中添加提交信息。 提交所有更改: git commit -a -m &q…...

【LeetCode】543.二叉树的直径

题目 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,5]…...

TypeScript教程(五)条件语句,循环,函数

一、条件语句 条件语句基于不同的条件来执行不同的动作 1.if语句&#xff1a;只有当指定条件为true时&#xff0c;使用该语句来执行代码 2.if...else语句&#xff1a;当条件为true时执行代码&#xff0c;当条件为else时执行其他代码 3.if...else if...else语句&#xff1a;…...

vue使用jsplumb 流程图

安装jsPlumb库&#xff1a;在Vue项目中使用npm或yarn安装jsPlumb库。 npm install jsplumb 创建一个Vue组件&#xff1a;创建一个Vue组件来容纳jsPlumb的功能和呈现。 <template><div style"margin: 20px"><div style"margin: 20px">&l…...

【BASH】回顾与知识点梳理(二十八)

【BASH】回顾与知识点梳理 二十八 二十八. 例行性工作排程(crontab)28.1 什么是例行性工作排程Linux 工作排程的种类&#xff1a; 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 界面&#xff0c;一般可以通过UI制作工具QtDesigner和纯代码编写两种方式来实现。纯代码实现暂时在这里不阐述了在后续布局章节详细说明&#xff0c;QtDesigner已经继承到开发环境中&#xff0c;在工程中直接双击ui文件就可以直接在QtDesigner设计器中打…...

[LitCTF 2023]Ping

因为直接ping会有弹窗。这里在火狐f12,然后f1选禁用javascript,然后ping 然后输入127.0.0.1;cat /flag 得到flag&#xff0c; 查看其他大佬的wp &#xff0c;这里还可以抓包。但是不知道为什么我这里的burp 用不了...

Spring Cloud面试突击班1

Spring Cloud面试突击班1 1.Spring Cloud 中有哪些组件&#xff0c;整个项目架构中我们的重点又有哪些&#xff1f; Spring Cloud 是一套基于Spring Boot的微服务解决方案。 Spring Cloud生态在国内主流的分为两套&#xff0c;一套是以奈飞开源的Spring Cloud Netfilx 20%&a…...

线上售楼vr全景看房成为企业数字化营销工具

在房地产业中&#xff0c;VR全景拍摄为买家提供了虚拟看房的全新体验。买家可以通过相关设备&#xff0c;远程参观各个楼盘的样板间和实景&#xff0c;感受房屋的空间布局和环境氛围&#xff0c;极大地提高了购房决策的准确性。对于房地产开发商和中介机构来说&#xff0c;VR全…...

“深入探索JVM内部机制:解密Java虚拟机原理“

标题&#xff1a;深入探索JVM内部机制&#xff1a;解密Java虚拟机原理 摘要&#xff1a;本文将深入探索Java虚拟机&#xff08;JVM&#xff09;的内部机制&#xff0c;揭示其工作原理和关键组成部分&#xff0c;包括类加载、内存管理、垃圾回收、即时编译和运行时数据区域等。…...

最长 上升子序列

大家好 我是寸铁 希望这篇题解对你有用&#xff0c;麻烦动动手指点个赞或关注&#xff0c;感谢您的关注 不清楚蓝桥杯考什么的点点下方&#x1f447; 考点秘籍 想背纯享模版的伙伴们点点下方&#x1f447; 蓝桥杯省一你一定不能错过的模板大全(第一期) 蓝桥杯省一你一定不…...

Nginx的介绍

本资料转载于传智教育-解锁你的IT职业薪未来&#xff0c;仅用于学习和讨论&#xff0c;如有侵权请联系 视频地址&#xff1a;04-Nginx的优点_哔哩哔哩_bilibili 资源文档&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1RlFl92FdxRUqc858JSxPSQ 提取码&#xff1a;12…...

[杂项]奥特曼系列影视列表大全

1966年&#xff1a;《奥特曼》「初代奥特曼」 1967年&#xff1a;《奥特赛文》 1971年&#xff1a;《归来的奥特曼》「杰克奥特曼」 1972年&#xff1a;《艾斯奥特曼》 1973年&#xff1a;《泰罗奥特曼》 1974年&#xff1a;《雷欧奥特曼》 1979年动画版&#xff1a;《乔尼亚斯…...

java代码日记--java 基础语法

java代码日记 在线运行 本地运行环境配置 Java 实例 实战 java8 Java 基础语法 一个Java程序可以认为是一系列对象的集合&#xff0c;而这些对象通过调用彼此的方法来协同工作。 下面简要介绍下类、对象、方法和实例变量的概念。 对象&#xff1a;对象是类的一个实例&…...

Spring中的IOC与DI-细胞内物质与传递

对IOC的认识 Spring Inversion of Control简称Spring IOC&#xff0c;是一种设计原则&#xff0c;通过它可以实现对象之间的解耦。通过Spring DI(Dependency Injection)依赖注入实现对象生命周期管理&#xff0c;为开发者提供对象创建、使用方式。 Spring中的Bean 在Spring框…...

【探索Linux】—— 强大的命令行工具 P.5(yum工具、git 命令行提交代码)

阅读导航 前言一、软件包管理器 yum1.yum的概念yum的基本指令使用例子 二、git 命令行提交代码总结温馨提示 前言 前面我们讲了C语言的基础知识&#xff0c;也了解了一些数据结构&#xff0c;并且讲了有关C的一些知识&#xff0c;也学习了一些Linux的基本操作&#xff0c;也了…...

jdbc 使用rewriteBatchedStatements=true后,报错

jdbc 使用rewriteBatchedStatementstrue后&#xff0c;报错了 rewriteBatchedStatementstrue解释 rewriteBatchedStatementstrue是一个配置选项&#xff0c;它影响MySQL JDBC驱动程序的行为。JDBC是Java数据库连接的标准。当你使用Java程序连接MySQL数据库时&#xff0c;你需要…...

第G1周:生成对抗网络(GAN)入门

&#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] 一、理论基础 生成对抗网络&#xff08;Generative Adversarial Networks, GAN&#xff09;是近年来深度学习领域…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

python可视化:俄乌战争时间线关键节点与深层原因

俄乌战争时间线可视化分析&#xff1a;关键节点与深层原因 俄乌战争是21世纪欧洲最具影响力的地缘政治冲突之一&#xff0c;自2022年2月爆发以来已持续超过3年。 本文将通过Python可视化工具&#xff0c;系统分析这场战争的时间线、关键节点及其背后的深层原因&#xff0c;全面…...

联邦学习带宽资源分配

带宽资源分配是指在网络中如何合理分配有限的带宽资源&#xff0c;以满足各个通信任务和用户的需求&#xff0c;尤其是在多用户共享带宽的情况下&#xff0c;如何确保各个设备或用户的通信需求得到高效且公平的满足。带宽是网络中的一个重要资源&#xff0c;通常指的是单位时间…...