C++中虚继承为什么可以解决菱形继承的数据冗余问题

news/2024/11/28 0:14:24/

        在C++中菱形继承会有数据冗余的问题发生,我们可以使用虚继承来解决,那虚继承的原理是什么,为什么它可以解决这个问题。

菱形继承的数据冗余问题

class A {
public:int data;
};class B : public A {};class C : public A {};class D : public B, public C {};

        在上述代码中,类 D 的对象在内存中会包含两份来自类 A 的成员变量 data(一份通过 B 继承而来,另一份通过 C 继承而来),这就导致了资源冗余的问题,并且在访问 data 成员时可能会产生二义性(因为不清楚具体要访问哪一份 data)

虚继承

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

        虚继承的实现机制主要通过在虚继承体系下创建一个虚基类表(virtual base class table,简称 vbtable)和调整对象的内存布局来解决资源冗余和二义性问题,具体如下:

在内存角度:

        在非虚继承的菱形继承中,派生类 D 的对象内存布局会依次包含 B 类部分(其中包含一份 A 的成员)和 C 类部分(其中又包含一份 A 的成员)。

         而在虚继承情况下,派生类 D 的对象内存布局会先有一个指向虚基类表(vbtable)的指针(如果有多个虚基类,可能只有一个这样的指针,具体实现依赖于编译器),然后是 B 类和 C 类各自特有的成员部分,而对于公共的虚基类 A 的成员,只会存在一份,通常放在对象内存布局的末尾(同样,具体位置和布局方式由编译器决定,但关键是只有一份)。

虚基类表的作用:

        虚基类表用于记录每个虚继承的派生类与虚基类之间的偏移量等信息。

        对于类 D,它通过虚继承同时继承了 B 和 C,而 B 和 C 又虚继承了 A。当 D 的对象需要访问虚基类 A 的成员时,会先通过对象中的虚基类表指针找到虚基类表,然后根据表中的偏移量信息,准确地定位到唯一一份虚基类 A 的成员所在位置,从而避免了访问到重复的成员,解决了资源冗余和二义性的问题。


http://www.ppmy.cn/news/1550468.html

相关文章

eduSRC挖洞思路

声明 学习视频来自 B 站UP主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 ✍🏻作者简介:致…

重写get方法导致json序列化之后值改变的问题

重写get方法导致json序列化之后值改变的问题 问题描述 在开发中,我发现有一个接口某一个字段返回的值和数据库中的实际值并不一样 数据库中值: id diameter 1 10接口返回值: {"id": 1,"diameter": 5 }问题排查 发现,在getDiame…

10 —— Webpack打包模式

开发模式:development ;场景:本地开发 生产模式:production ; 场景:打包上线 这两种模式如何设置给webpack: 方式1.webpack.config.js 配置文件设置mode选项 module.exports { mode:produc…

tsx中使用el-dialog设置visible.sync,解决弹窗右上角叉号失效问题

在 TSX 中使用 el-dialog 设置 visible.sync 在 Vue 2 中,.sync 修饰符用于在父子组件之间同步属性值。然而,在 TSX 中并没有类似的 .sync 修饰符。如果要在 TSX 中实现类似的功能,需要手动实现。具体来说,可以通过监听 update:v…

Jackson 对象与json数据互转工具类JacksonUtil

下面是一个基于 Jackson 的工具类 JacksonUtil,用于在 Java 项目中实现对象与 JSON 数据之间的互相转换。该工具类具有简洁、易用、通用的特点。 package com.fy.common.util;import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core…

SQL99版外连接

外连接 看这样的场景,在ta和tb两表中查询没有对应年龄数据的学生姓名和年龄 SELECT tb.name,ta.age FROM tb INNER JOIN ta ON tb.ta_idta.id WHERE ta.id IS NULL; 结果没有,所以前面的查询是解决不了这种问题!!! 所以外连接…

Spring Boot 核心逻辑与工作原理详解

当然可以!下面是一篇关于 Spring Boot 逻辑的文章,涵盖了其核心概念、主要特点和工作原理。 Spring Boot 的逻辑与工作原理 1. 引言 Spring Boot 是一个基于 Java 的框架,旨在简化新 Spring 应用的初始搭建和开发过程。它通过提供默认配置和…

第六章 Spring Boot快速⼊⻔ —— Spring Boot工作机制

前言: Spring Boot的工作机制主要围绕其自动配置、起步依赖、嵌入式Web服务器以及配置管理等方面展开。 自动配置:是通过预定义的约定和条件,它极大地简化了应用的开发过程,这一机制使得开发人员可以更加专注于业务逻辑的实现,而无需花费大量时间在繁琐的配置上。起步依赖…