C++:菱形继承问题

目录

1、什么是菱形继承

2、虚拟继承

3、一些常见问题

1. 什么是菱形继承?菱形继承的问题是什么?

2. 什么是菱形虚拟继承?如何解决数据冗余和二义性的

3. 继承和组合的区别?什么时候用继承?什么时候用组合?


1、什么是菱形继承

在C++中,菱形继承是指一个派生类同时继承自两个直接或间接基类,而这两个基类又继承自同一个基类。这种继承结构形成了一个菱形的图形,因此得名菱形继承。菱形继承可能会引起一些问题,其中最主要的问题是数据冗余。由于派生类继承了两个基类,这两个基类都可能包含相同的数据成员,导致派生类中存在两份相同的数据,造成数据冗余和浪费内存。

单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
菱形继承:菱形继承是多继承的一种特殊情况。
菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。
Assistant 的对象中 Person 成员会有两份。
我们来看一个例子
class Person
{
public:string _name; // 姓名
};
class Student : public Person
{
protected:int _num; //学号
};
class Teacher : public Person
{
protected:int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};
void Test()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter";// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

菱形继承有数据冗余和二义性的问题

2、虚拟继承

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在 Student
Teacher 的继承 Person 时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地
方去使用。
class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person
{
protected:int _num; //学号
};
class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};
void Test()
{// 这样可以解决二义性和数据冗余Assistant a;a._name = "peter";
}

通过内存窗口观察对象成员的模型来研究虚拟继承原理
class A
{
public:int _a;
};
class B : public A
//class B : virtual public A
{
public:int _b;
};class C : public A
//class C : virtual public A
{
public:int _c;
};
class D : public B, public C
{
public:int _d;
};
void Test()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;
}
从上图可以看到0x00EFF67C和0x00EFF684都是_a,这就是数据冗余。
下面我们使用虚拟继承来观察
可以看到原来_a的地址存放了两个新的地址,而_a存在了_d的下一个位置,我们来观察这两个地址
B到A偏移量为20,C到A偏移量为12
这里是通过了 B C 的两个指针,指 向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量 可以找到下面的 A
现在就可以对Person虚拟继承进行解释

3、一些常见问题

1. 什么是菱形继承?菱形继承的问题是什么?

菱形继承是指一个派生类同时继承自两个直接或间接基类,而这两个基类又继承自同一个基类。这种继承结构形成了一个菱形的图形,因此得名菱形继承。
菱形继承会引发数据冗余和二义性问题。

2. 什么是菱形虚拟继承?如何解决数据冗余和二义性的

菱形虚拟继承是C++中用来解决菱形继承问题的一种技术。通过使用虚拟继承,可以避免数据冗余和虚基类指针二义性问题。在菱形虚拟继承中,共同的基类被标记为虚基类,这样在派生类中只会保留一份虚基类的数据成员,从而避免了数据冗余。此外,虚基类指针也只会指向虚基类的唯一实例,消除了二义性。

3. 继承和组合的区别?什么时候用继承?什么时候用组合?

public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。
组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。
继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称
为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的
内部细节对子类可见 。 继承一定程度破坏了基类的封装,基类的改变,对派生类有很
大的影响。派生类和基类间的依赖关系很强,耦合度高。
对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象
来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复
用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。
组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被
封装。
实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有
些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用
继承,可以用组合,就用组合。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 自定义长条进度条(类似播放器进度条)

1.运行界面 2.步骤 其实很简单。 2.1绘制底图圆角矩形 2.2绘制播放进度圆角矩形 参考&#xff1a;painter绘图 3.源码 #pragma once#include <QWidget> #include <QLabel> #include <QHBoxLayout> #include <QMouseEvent> #include <QDebug&g…

Slicer学习笔记(六十五) 3DSlicer的医学图像数据增强扩展模块

1. 医学图像数据增强扩展模块 基于3D Slicer5.1.0 编写了一个测试医学图像的数据增强测试扩展模块。 扩展模块名&#xff1a;DataAugementation 项目地址&#xff1a;DataAugmentation 下载该项目后&#xff0c;可以将该扩展模块添加到3D Slicer的扩展中。 关于如何给3DSlicer…

微信自动回复,基于python

#!/usr/bin/python3 # -*- coding: utf-8 -*-import numpy as np import pandas as pd from uiautomation import WindowControl import csvwx WindowControl(Name微信,searchDepth1 ) # 切换窗口 wx.ListControl() wx.SwitchToThisWindow() # 寻找会话控件绑定 hw wx.…

LaTeX-设置表格大小

文章目录 LaTeX-设置表格大小1.创建表格2.设置表格的宽度2.1控制表格每一列的宽度2.2控制整个表格的宽度 3.设置表格的外观4.LaTeX绘制三线表 LaTeX-设置表格大小 本文介绍了LaTeX如何设置表格的大小、改变表格的外观以及如何绘制三线表。 1.创建表格 在LaTeX中创建表很耗时…

【前端素材】推荐优质后台管理系统网页my-Task平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;通常由管理员使用。后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功…

2023年NOC大赛软件创意编程(学而思)赛道图形化小低高组决赛试题

2023NOC 决赛-小低组 每个小朋友从小会有梦寐以求的愿望,或是拥有孙悟空七十二变的能 力,或是像神笔马良一样想要什么画什么,或是成为人见人爱的国宝 大熊猫,或是变身全能机器人……今天,你可以用编程实现自己愿望! 【题目要求】 请以“假如我是_____”为题,自选主…

Sentinel实战(待完善)

目录 服务雪崩 什么是服务雪崩 服务不可用原因 解决方案 技术选型对比 Sentinel 介绍 优点 核心概念 资源 规则 代码实战 API实现 SentinelResource注解实现 Sentinel控制台 启动控制台服务 java应用接入控制台 微服务接入Sentinel 服务雪崩 什么是服务雪崩…

DETR详解

1. 动机 传统的目标检测任务需要大量的人工先验知识&#xff0c;例如预定义的先验anchor&#xff0c;NMS后处理策略等。这些人工先验知识引入了很多人为因素&#xff0c;且较难处理。如果能够端到端到直接生成目标检测结果&#xff0c;将会使问题变得很优雅。 2. 主要贡献 提…

idea中maven配置(一次成功,全部细节都有)

写这篇文章的原因是maven的配置很简单&#xff0c;但是也很容易出错&#xff0c;我连配了两台电脑的maven出现了各种小错误&#xff0c;参考了以下两篇博文IDEA配置Maven教程&#xff08;超详细版~)_idea maven配置教程-CSDN博客 一次包会——最新IDEA配置Maven指南&#xff0…

python 基础知识点(蓝桥杯python科目个人复习计划57)

今日复习计划&#xff1a;做题 例题1&#xff1a;笨笨的机器人 问题描述&#xff1a; 肖恩有一个机器人&#xff0c;他能根据输入的指令移动相应的距离。但是这个机器人很笨&#xff0c;他永远分不清往左边还是往右边移动。肖恩也知道这一点&#xff0c;所以他设定这个机器人…

mysql 远程不允许连接 1130 -Host ‘‘ is not allowed to connect to this MySQL server

1、docker 进入mysql 命令 sudo docker exec -it 0c58 /bin/bash 2、连接mysql mysql -u root -ppwd 3、 use mysql; 4、更改表所有root用户都可以连接 update user set host ‘%’ where user‘root’; 5、刷新权限 flush privilege&#xff1b; ok解决&#xff1b;

五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等

hello&#xff0c;我是贝格前端工场&#xff0c;本次介绍跨平台开发的框架&#xff0c;欢迎大家评论、点赞。 一、什么是跨平台桌面应用开发框架 跨平台桌面应用开发框架是一种工具或框架&#xff0c;它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的…

3.2日学习打卡----初学FastDFS(二)

3.2日学习打卡 目录: 3.2日学习打卡SpringBoot整合FastDFS实战开发文件上传 FastDFS集成Nginx环境搭建 SpringBoot整合FastDFS 由GitHub大牛tobato在原作者YuQing与yuqih发布的JAVA客户端基础上进行了大量重构工作&#xff0c;并于GitHub上发布了FastDFS-Client1.26.5。 主要特…

现货大宗商品发售平台搭建须知

在搭建现货大宗商品发售平台时&#xff0c;需要考虑以下关键因素&#xff1a; 目标市场分析&#xff1a;首先要明确你的平台将服务于哪些大宗商品市场&#xff0c;如农产品、金属、能源等。了解这些市场的特点、参与者、交易规则等&#xff0c;有助于你设计出更符合市场需求的…

chromedriver,Chrome驱动的实时更新

发现自己的selenium项目跑不起来了 效验驱动版本 下载链接(可能需要魔法) https://registry.npmmirror.com/binary.html?pathchromedriver/ https://googlechromelabs.github.io/chrome-for-testing/ 找到驱动位置 1. 默认安装路径&#xff1a;Chrome驱动通常会默认安装在系…

详解JavaScript的函数

详解 JavaScript 的函数 函数的语法格式 创建函数/函数声明/函数定义 function 函数名(形参列表) { 函数体 return 返回值; // return 语句可省略 } 函数调用 函数名(实参列表) // 不考虑返回值 返回值 函数名(实参列表) // 考虑返回值 示例代码 //定义的没有参数列表&am…

实验:依赖注入之setter注入

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

【数据结构与算法】整数二分

问题描述 对一个排好序的数组&#xff0c;要求找到大于等于7的最小位置和小于等于7的最大位置 大于等于7的最小位置 易知从某个点开始到最右边的边界都满足条件&#xff0c;我们要找到这个区域的最左边的点。 开始二分&#xff01; left指针指向最左边界&#xff0c;right…

2024-03-01(金融AI行业与大数据生态圈)

1.金融这一块的算法&#xff0c;不像推荐系统&#xff0c;图像等领域&#xff0c;金融领域的算法都比较成熟了。现在来说门槛低&#xff0c;属于初期阶段&#xff0c;上升期。 2.反欺诈的数据标签比较少&#xff0c;有一种“标签染色”的方法来做反欺诈模型的标签。 3.常用反…

官宣 | 凯琦供应链成为亚马逊SPN物流服务商!

再播一条喜讯&#xff01;在亚马逊官方平台的筛选考核下&#xff0c;凯琦供应链近日正式入驻亚马逊SPN服务商平台&#xff0c;成为亚马逊SPN第三方承运商。 这也标志着凯琦9年来在FBA物流领域的服务质量得到了客户、官方及行业的广泛认可&#xff0c;未来凯琦将继续为亚马逊卖家…