什么是虚拟继承

由于C++支持多继承,除了public、protected和private三种继承方式外,还支持虚拟(virtual)继承,举个例子:

#include <iostream>
using namespace std;

class A {};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};

int main()
{
    cout << "sizeof(A):" << sizeof A << endl; // 1,空对象,只有一个占位
    cout << "sizeof(B):" << sizeof B << endl; // 4,一个bptr指针,省去占位,不需要对齐
    cout << "sizeof(C):" << sizeof C << endl; // 4,一个bptr指针,省去占位,不需要对齐
    cout << "sizeof(D):" << sizeof D << endl; // 8,两个bptr,省去占位,不需要对齐
}

/*
    sizeof(A):1
    sizeof(B):8
    sizeof(C):8
    sizeof(D):16
*/

上述代码所体现的关系是,B和C虚拟继承A,D又公有继承B和C,这种方式是一种菱形继承或者钻石继承,可以用如下图来表示:

 

 

虚拟继承的情况下,无论基类被继承多少次,只会存在一个实体。**虚拟继承基类的子类中,子类会增加某种形式的指针,或者指向虚基类子对象,或者指向一个相关的表格;表格中存放的不是虚基类子对象的地址,就是其偏移量,此类指针被称为bptr,如上图所示。如果既存在vptr又存在bptr,某些编译器会将其优化,合并为一个指针。

虚拟继承是一种多重继承的特殊形式,它的目的是解决菱形继承中的冗余数据和二义性问题¹。

菱形继承是指一个派生类继承了两个或多个直接基类,而这些直接基类又继承自同一个间接基类,形成了一个菱形的继承结构²。例如:

class A {
  // 间接基类
};

class B: public A {
  // 直接基类
};

class C: public A {
  // 直接基类
};

class D: public B, public C {
  // 派生类
};

在这种情况下,派生类 D 中会包含两份间接基类 A 的成员,一份来自 B,一份来自 C。这样会造成以下问题³:

  • 冗余数据:派生类 D 中的两份 A 的成员占用了多余的内存空间,而且可能存储了不一致的数据。
  • 二义性:当派生类 D 中访问 A 的成员时,编译器无法确定是访问 B 中的 A 还是 C 中的 A,需要显式地指定路径,否则会报错。

为了解决这些问题,可以使用虚拟继承,即在继承方式前加上 virtual 关键字,表示该基类是一个虚拟基类,例如:

class A {
  // 间接基类
};

class B: virtual public A {
  // 直接基类
};

class C: virtual public A {
  // 直接基类
};

class D: public B, public C {
  // 派生类
};

这样,派生类 D 中就只保留了一份间接基类 A 的成员,不会出现冗余数据和二义性问题。虚拟继承的原理是通过虚基指针和虚基表来实现的,每个包含虚拟基类的类都有一个虚基指针,指向一个虚基表,虚基表中存放了虚拟基类的偏移量,用于定位虚拟基类的位置⁴。

虚拟继承的作用是在多重继承的情况下,保证间接基类的实例只会在派生类对象中存在一次,而不会重复出现。这样可以避免数据的冗余和访问的二义性,也可以节省内存空间和提高效率。虚拟继承是一种复杂的继承方式,一般不推荐使用,除非在必要的情况下。多重继承本身就容易引起设计上的混乱和错误,所以在实际开发中应该尽量避免使用多重继承,或者使用单一继承和组合的方式来代替多重继承。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/482276.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大学形势与政策~秋试题及答案,分享几个实用搜题和学习工具 #媒体#笔记

大学生必备&#xff0c;这条笔记大数据一定定要推给刚上大学的学弟学妹&#xff01;&#xff01; 1.白鸽搜题 这个是公众号 超强题库资源&#xff0c;涵盖行业单位、学历提升等各类考试。解题更轻松&#xff0c;学习更高效。 下方附上一些测试的试题及答案 1、外部招募的主…

【数据库】聚合函数

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;清灵白羽 漾情天…

虚拟机Ubuntu无法识别U盘

1. 现象 虚拟机插入U盘后&#xff0c;无反应。系统中也找不到U盘。 2. 原因 VMware USB Arbitration Service服务别关闭了&#xff0c;任务管理器中找不到该任务。 服务中也没有运行&#xff08;services.msc&#xff09; 3. 解决 打开服务设置窗口&#xff08;services.…

温湿度项目设计V1.0——PCB布线及打板

PCB布线 画好原理图之后&#xff0c;通过工具——标注所有器件&#xff0c;当前原理图上的器件编号会被自动标注号。点击设置——Update PCB Document文件名&#xff0c;弹出的界面先点击生效变更&#xff0c;然后点击执行变更。界面会跳转到PCB界面。如果生效变更有问题&…

城管智慧执法系统源码,基于微服务+java+springboot+vue开发

城管智慧执法系统源码&#xff0c;基于微服务javaspringbootvue开发 城管智慧执法系统源码有演示&#xff0c;自主研发&#xff0c;功能完善&#xff0c;正版授权&#xff0c;可商用上项目。 一套数字化的城管综合执法办案系统源码&#xff0c;提供了案件在线办理、当事人信用…

开学考核复现

不要尝试爆破哟!(misc) 下载图片&#xff0c;解析图片 拿到密码&#xff0c;解压压缩包&#xff0c;生成图片 扫描二维码 留个后门(misc) D盾扫描 打开文件寻找 师姐的旅游照片(misc) 随波逐流&#xff0c;然后base64解码 修改后缀为zip&#xff0c;解压 修改高度 Fuck! (C…

「媒体宣传」企业活动发布会邀请媒体报道的好处与优势?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 企业活动发布会邀请媒体报道具有多种好处与优势&#xff0c;这些都有助于提升企业的知名度、形象和影响力。以下是一些主要的好处与优势&#xff1a; 提升品牌知名度&#xff1a;媒体报道…

MATLAB环境下基于离散小波变换和主成分平均的医学图像融合方法

随着计算机技术和生物影像工程的日趋成熟&#xff0c;医学图像为医疗诊断提供的信息越来越丰富。目前&#xff0c;由于医学成像的设备种类繁多&#xff0c;导致医生获得的图像信息差异较大。如何把这些信息进行整合供医生使用成为当务之急。基于此&#xff0c;医学图像融合技术…

Windows下安装QT,遇到下载组件中没有指定版本(提供解决方式) + 5.15详细安装步骤版

Windows下安装QT 5.15详细安装问题详解 前情提要一、QT 5.15及之后版本的下载问题二、QT 5.15及之后版本的下载方式&#xff1a;下载QT(在线安装版本)三、详细安装步骤遇到<下载组件>中没有指定版本的解决方式 前情提要 嵌入式设备搭载的QT版本是5.15&#xff0c;所以PC…

【C语言】预处理编译链接调试技巧详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;C语言_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.预处理 1.1 预定义符号 1.2 #define 1.2.1 #define 定义标识符 1.2.2 #define 定义宏 1.2.3 #define 替换规则 1.2.4 #和## …

23. UE5 RPG制作属性面板(一)

随着角色的属性越来越多&#xff0c;我们不能每次都进行showdebug abilitysystem进行查看&#xff0c;而且玩家也需要查看角色属性&#xff0c;所以需要一个查看玩家角色属性的面板。 在前面&#xff0c;我们创建三种类型的属性 Primary Attributes&#xff08;主要属性&#…

prettier + eslint 配置

vue-cli 新建项目选择 ESLint Prettier 会自动下载相关包 settings.json {"editor.formatOnSave": true, // 开启保存文件自动格式化代码"editor.defaultFormatter": "esbenp.prettier-vscode", // 默认的代码格式化工具// "prettier.r…

11 Games101 - 笔记 - 几何(曲线与曲面)

11 几何&#xff08;曲线与曲面&#xff09; 贝塞尔曲线 定义 贝塞尔曲线&#xff1a;由控制点和线段组成的曲线&#xff0c;控制点是可拖动的支点。 如图&#xff0c;蓝色为贝塞尔曲线&#xff0c;p1, p2, p3为控制点&#xff0c;曲线和初始与终止端点相切&#xff0c;并且…

数字乡村引领新风尚:科技赋能农村实现全面进步

随着信息技术的迅猛发展&#xff0c;数字乡村正成为引领农村全面进步的新风尚。科技作为推动农村发展的强大引擎&#xff0c;正在深刻改变着传统农业的生产方式、农村的社会结构以及农民的生活方式&#xff0c;为农村经济社会的全面进步注入了新的活力和动力。本文将从数字乡村…

【深度学习】四种天气分类 模版函数 从0到1手敲版本

引入该引入的库 import torch import torch.nn as nn import matplotlib.pyplot as plt import torch.nn.functional as F import torchvision import torch.optim as optim %matplotlib inline import os import shutil import glob os.environ["KMP_DUPLICATE_LIB_OK&q…

双指针算法:三数之和

文章目录 一、[题目链接&#xff1a;三数之和](https://leetcode.cn/problems/3sum/submissions/515727749/)二、思路讲解三、代码演示 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的支持就是我坚持…

马蹄集oj赛(双周赛第二十三次)

目录 数列分割 小码哥的地毯 小码哥的三色墙 palace 高数考试 新全排列 黑白双煞 等差 数三角形 区间修改 相对马高 小码哥剪绳子 数列分割 难度:黄金 时间限制:1秒巴 占用内存:64 M 小码哥给你一个长度为n的数列&#xff0c;求将该数列分割成两个左右两个部分且两…

大模型学习笔记七:LLM应用

文章目录 一、维护生产级别的LLM应用,需要做的事二、符合需求的LLM App维护平台三、LangFuse1)替换OpenAI客户端(把跟OpenAI交互记录到LangFuse)1.1)几个基本概念2)通过LangChain的回调函数触发记录(上面用的原生OpenAI接口,下面是调用LangChain的接口)3)构建一个实际…

打开snipaste软件的界面后,上次的截图无法销毁?

现象&#xff1a; 鼠标放上去&#xff0c;如图会有1个圆圈&#xff0c;无法消除一直显示在电脑桌面上&#xff0c;无法使图片消失 解决办法&#xff1a; 你应该是点到了空格&#xff0c;开启了编辑模式&#xff0c;然后又选中了其中一个功能例如橡皮檫导致无法移动和销毁&…

Linux线程补充1

十、多线程中线程间的"独立" ​ 1.线程在代码段通过执行不同的函数&#xff0c;实现代码段的独立&#xff1b; ​ 2.新线程通过在共享区划分不同的管理属性和不同的栈空间&#xff0c;实现栈的独立&#xff0c;而主线程使用的是栈空间&#xff1b; ​ 3.线程通过获…
最新文章