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

C++中的菱形继承问题

假设有一个问题,类似于鸭子这样的动物有很多种,如企鹅和鱿鱼,它们也可能会有一些共同的特性。例如,我们可以有一个叫做 AquaticBird (涉禽,水鸟的一类)的类,它又继承自 Animal 和 SwimmingAnimal,就像这样:

class AquaticBird : public Animal, public SwimmingAnimal {  // AquaticBird类既是Animal也是SwimmingAnimal  
};  

如果我们同时继承了这两个类,像下图所示,将发生菱形继承:

        Animal  /      \
FlyingAnimal   AquaticBird  \      /  Duck  

在这个结构中,Duck 既继承了 FlyingAnimal,也间接继承了 Animal 通过 AquaticBird 的方式。问题在于,如果我们试图调用 Animal 类的方法,例如 eat(),Duck 会造成二义性:它不清楚是通过哪个路径来调用 Animal 类的实例。

那么如何解决菱形继承问题呢

解决菱形继承问题

通过使用 虚继承,我们可以确保在最终的 Duck 类中,只有一个 Animal 的实例。


class Animal {  
public:  void eat() {  std::cout << "Eating food." << std::endl;  }  
};  
class FlyingAnimal : virtual public Animal { // 使用virtual  
public:  void fly() {  std::cout << "Flying." << std::endl;  }  
};  
class SwimmingAnimal : virtual public Animal { // 使用virtual  
public:  void swim() {  std::cout << "Swimming." << std::endl;  }  
};  
class Duck : public FlyingAnimal, public SwimmingAnimal {  // Duck类继承自FlyingAnimal和SwimmingAnimal  
};  

现在,当 Duck 类调用 eat() 方法时,编译器知道只有一份 Animal 的实例,从而避免了二义性。

那么虚继承的底层实现原理是什么呢?

g++ -fdump -class-hlerarchy *.cpp gcc8.0之前

g++ fdump -lang - class *.cpp gcc8.0及以后

通过虚表指针偏移来实现虚继承

父类的vptr都有到共同基类的偏移量,从而让子类多继承是指向同一个“父类的父类”

只有C++有菱形继承

一般不使用菱形继承,但在库里面使用了

如下所示,下面的箭头都是继承,我们就会发现中间出现了菱形继承,iostream继承了istream和ostream。

相关文章:

C++中的菱形继承问题

假设有一个问题&#xff0c;类似于鸭子这样的动物有很多种&#xff0c;如企鹅和鱿鱼&#xff0c;它们也可能会有一些共同的特性。例如&#xff0c;我们可以有一个叫做 AquaticBird &#xff08;涉禽&#xff0c;水鸟的一类&#xff09;的类&#xff0c;它又继承自 Animal 和 Sw…...

订单越来越到导致接口列表查询数据缓慢解决思路

文章目录 **一、前期诊断&#xff1a;定位性能瓶颈****1. 数据现状分析****2. 业务场景梳理** **二、基础优化&#xff1a;快速提升性能****1. 索引精准优化****2. 表结构优化&#xff08;垂直分表&#xff09;****3. 读写分离与缓存策略** **三、架构升级&#xff1a;应对千万…...

word格式相关问题

页眉 1 去除页眉横线&#xff1a; 双击打开页眉&#xff0c;然后点击正文样式&#xff0c;横线就没有了。 2 让两部分内容的页眉不一样&#xff1a; 使用“分节符”区分两部分内容&#xff0c;分节符可以在“布局-分隔符”找到。然后双击打开页眉&#xff0c;取消“链接到前一…...

网络-MOXA设备基本操作

修改本机IP和网络设备同网段&#xff0c;输入设备IP地址进入登录界面&#xff0c;交换机没有密码&#xff0c;路由器密码为moxa 修改设备IP地址 交换机 路由器 环网 启用Turbo Ring协议&#xff1a;在设备的网络管理界面中&#xff0c;找到环网配置选项&#xff0c;启用Turb…...

飞桨paddle import fluid报错【已解决】

跟着飞桨的安装指南安装了paddle之后 pip install paddlepaddle有一个验证&#xff1a; import paddle.fluid as fluid fluid.install check.run check()报错情况如下&#xff0c;但是我在pip list中&#xff0c;确实看到了paddle安装上了 我import paddle别的包&#xff0c…...

测试工程师要如何开展单元测试

单元测试是软件开发过程中至关重要的环节&#xff0c;它通过验证代码的最小可测试单元(如函数、方法或类)是否按预期工作&#xff0c;帮助开发团队在早期发现和修复缺陷&#xff0c;提升代码质量和可维护性。以下是测试工程师开展单元测试的详细步骤和方法&#xff1a; 一、理…...

IPv4 地址嵌入 IPv6 的前缀转换方式详解

1. 概述 在 IPv4 和 IPv6 网络共存的过渡期&#xff0c;NAT64&#xff08;Network Address Translation 64&#xff09;是一种关键技术&#xff0c;用于实现 IPv6-only 网络与 IPv4-only 网络的互操作。NAT64 前缀转换通过将 IPv4 地址嵌入到 IPv6 地址中&#xff0c;允许 IPv…...

野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(三)用yolov5-face算法实现人脸检测

环境直接使用第一篇中安装好的环境即可 先clone yolov5-face项目 git clone https://github.com/deepcam-cn/yolov5-face.git 并下载预训练权重文件yolov5n-face.pt 网盘链接: https://pan.baidu.com/s/1xsYns6cyB84aPDgXB7sNDQ 提取码: lw9j &#xff08;野火官方提供&am…...

IS-IS 中间系统到中间系统

前言&#xff1a; 中间系统到中间系统IS-IS&#xff08;Intermediate System to Intermediate System&#xff09;属于内部网关协议IGP&#xff08;Interior Gateway Protocol&#xff09;&#xff0c;用于自治系统内部 IS-IS也是一种链路状态协议&#xff0c;使用最短路径优先…...

【图像生成大模型】HunyuanVideo:大规模视频生成模型的系统性框架

HunyuanVideo&#xff1a;大规模视频生成模型的系统性框架 引言HunyuanVideo 项目概述核心技术1. 统一的图像和视频生成架构2. 多模态大语言模型&#xff08;MLLM&#xff09;文本编码器3. 3D VAE4. 提示重写&#xff08;Prompt Rewrite&#xff09; 项目运行方式与执行步骤1. …...

GitHub 趋势日报 (2025年05月19日)

本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1public-apis/public-apis免费API的集体清单⭐ 1821⭐ 344364Python2virattt/a…...

如何使用Java生成pdf报告

文章目录 一、环境准备与Maven依赖说明二、核心代码解析1. 基础文档创建2. 中文字体处理3. 复杂表格创建4. 图片插入 三、完整代码示例四、最终效果 这篇主要说一下如何使用Java生成pdf&#xff0c;包括标题&#xff0c;文字&#xff0c;图片&#xff0c;表格的插入和调整等相关…...

HarmonyOS鸿蒙应用规格开发指南

在鸿蒙生态系统中&#xff0c;应用规格是确保应用符合系统要求的基础。本文将深入探讨鸿蒙应用的规格开发实践&#xff0c;帮助开发者打造符合规范的应用。 应用包结构规范 1. 基本配置要求 包结构规范 符合规范的应用包结构正确的HAP配置文件完整的应用信息 示例配置&…...

【Harmony】【鸿蒙】List列表View如何刷新内部的自定义View的某一个控件

创建自定义View Component export struct TestView{State leftIcon?:Resource $r(app.media.leftIcon)State leftText?:Resource | string $r(app.string.leftText)State rightText?:Resource | string $r(app.string.rightText)State rightIcon?:Resource $r(app.med…...

iisARR负均衡

IIS ARR负载均衡详细配置指南 &#x1f3af; 什么是ARR&#xff08;Application Request Routing&#xff09; ARR是IIS的一个扩展模块&#xff0c;它可以&#xff1a; 负载均衡&#xff1a;将请求分发到多个服务器反向代理&#xff1a;隐藏后端服务器架构健康检查&#xf…...

uniapp打包报错:重新在manifest.json中生成自己的APPID

在UniApp开发过程中&#xff0c;打包时可能会遇到报错提示需要在manifest.json中重新生成自己的APPID。以下是解决该问题的具体方法&#xff1a; 检查并生成APPID 打开项目根目录下的manifest.json文件&#xff0c;找到appid字段。如果该字段为空或为默认值&#xff0c;需要重…...

人脸识别备案开启安全防护模式!紧跟《办法》!

国家互联网信息办公室与公安部于 2025 年 3 月 13 日联合公布了《人脸识别技术应用安全管理办法》&#xff08;以下简称《办法》&#xff09;&#xff0c;并自 2025 年 6 月 1 日起正式施行。其中&#xff0c;人脸识别备案成为了规范技术应用、守护信息安全的关键一环。​ 一、…...

【爬虫】DrissionPage-7

官方文档&#xff1a; https://www.drissionpage.cn/browser_control/get_page_info/ 1. 页面信息 &#x1f4cc; html 描述&#xff1a;返回当前页面的 HTML 文本。注意&#xff1a;不包含 <iframe> 元素的内容。返回类型&#xff1a;str 示例&#xff1a; html_co…...

新浪《经济新闻》丨珈和科技联合蒲江政府打造“数字茶园+智能工厂+文旅综合体“创新模式

5月14日&#xff0c;新浪网《经济新闻》频道专题报道珈和科技在第十四届四川国际茶业博览会上的精彩亮相&#xff0c;并深度聚焦我司以数字技术赋能川茶产业高质量发展创新技术路径&#xff0c;及在成都市“茶业建圈强链”主题推介会上&#xff0c;珈和科技与蒲江县人民政府就智…...

git 撤销最近的几次push

要实现将远程仓库回退到最近5次push之前的状态&#xff0c;同时保留本地改动&#xff0c;可以按照以下步骤操作&#xff1a; 一、本地分支回退&#xff08;保留改动&#xff09; # 1. 查看提交历史确认要回退的提交点 git log --oneline# 2. 回退到5次提交前的状态&#xff0…...

水滴前端面经及参考答案

盒模型是什么,标准盒模型和 IE 盒模型有什么区别? 盒模型是 CSS 中一个基础概念,它描述了元素在页面中所占的空间大小。每个元素都可以看作是一个矩形盒子,从内到外由内容区(content)、内边距(padding)、边框(border)和外边距(margin)组成。 标准盒模型的宽度和高…...

React 第四十五节 Router 中 useHref() Hook的使用详解及注意事项

前言 React Router 中的 useHref 是一个用于生成完整 URL 路径的钩子&#xff0c; 它可以将相对路径解析为绝对路径&#xff0c;并确保在不同路由层级中正确工作。 它常用于自定义导航组件或需要手动构建链接的场景。 一、useHref核心用途 解析相对路径&#xff1a;自动将相…...

50、js 中var { ipcRenderer } = require(‘electron‘);是什么意思?

在 JavaScript 中&#xff0c;var { ipcRenderer } require(‘electron’); 这行代码的含义是&#xff1a; 1. require(‘electron’) 这是 Node.js 的模块引入语法&#xff0c;用于加载 Electron 的核心模块。electron 是 Electron 框架的主模块&#xff0c;提供了构建桌面…...

LeetCode 438. 找到字符串中所有字母异位词 | 滑动窗口与字符计数数组解法

文章目录 问题描述核心思路&#xff1a;滑动窗口 字符计数数组1. 字符计数数组2. 滑动窗口 算法步骤完整代码实现复杂度分析关键点总结类似问题 问题描述 给定两个字符串 s 和 p&#xff0c;要求找到 s 中所有是 p 的**字母异位词&#xff08;Anagram&#xff09;**的子串的起…...

@RequestParam 和 @RequestBody、HttpServletrequest 与HttpServletResponse

在Java Web开发中&#xff0c;RequestParam、RequestBody、HttpServletRequest 和 HttpServletResponse 是常用的组件&#xff0c;它们用于处理HTTP请求和响应。下面分别介绍它们的使用场景和使用方法&#xff1a; 1. RequestParam RequestParam 是Spring MVC框架中的注解&am…...

计算机底层的多级缓存以及缓存带来的数据覆盖问题

没有多级缓存的情况 有多级缓存的情况 缓存带来的操作覆盖问题 锁总线带来的消耗太大了。...

SpringBoot-1-入门概念介绍和第一个Spring Boot项目

文章目录 1 开发JAVA EE应用1.1 EJB1.2 Spring框架1.2.1 IoC(Inversion of Control)控制反转1.2.2 DI(Dependency Injection)依赖注入1.2.3 AOP面向切面编程1.3 Spring Boot1.4 Spring Cloud框架1.5 开发工具2 创建Spring Boot项目2.1 在线项目生成向导2.2 使用IDEA导入项目2.3…...

服务器多用户共享Conda环境操作指南——Ubuntu24.02

1. 使用阿里云镜像下载 Anaconda 最新版本 wget https://mirrors.aliyun.com/anaconda/archive/Anaconda3-2024.02-1-Linux-x86_64.sh bug解决方案 若出现&#xff1a;使用wget在清华镜像站下载Anaconda报错ERROR 403: Forbidden. 解决方案&#xff1a;wget --user-agent“M…...

基于FPGA的电子万年历系统开发,包含各模块testbench

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于FPGA的电子万年历系统开发,包含各模块testbench。主要包含以下核心模块&#xff1a; 时钟控制模块&#xff1a;提供系统基准时钟和计时功能。 日历计算模块&#xff1a…...

Leetcode刷题 | Day63_图论08_拓扑排序

一、学习任务 拓扑排序代码随想录 二、具体题目 1.拓扑排序117. 软件构建 【题目描述】 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依…...