复杂的菱形继承及菱形虚拟继承(详解)

news2024/10/7 3:18:41

复杂的菱形继承及菱形虚拟继承

  • 复杂的菱形继承及菱形虚拟继承
  • 虚拟继承解决数据冗余和二义性的原理
  • 笔试面试题

复杂的菱形继承及菱形虚拟继承

  • 单继承:一个子类只有一个直接父类时称这个继承关系为单继承
    在这里插入图片描述

  • 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
    在这里插入图片描述

  • 菱形继承:菱形继承是多继承的一种特殊情况。(不推荐用,坑!)
    在这里插入图片描述


菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在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";//会报错("Assistant::_name不明确")
	// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
	a.Student::_name = "xxx";
	a.Teacher::_name = "yyy";
}

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在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";
}

虚拟继承解决数据冗余和二义性的原理

为了研究虚拟继承原理,我们给出了一个简化的菱形继承继承体系,再借助内存窗口观察对象成员的模型。

#include <iostream>
using namespace std;

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;
};
int main()
{
	D d;
	d.B::_a = 1; 
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}

不使用虚继承(class C : public A):

在这里插入图片描述


使用虚继承(class C : virtual public A)

在这里插入图片描述

笔试面试题

  1. 什么是菱形继承?菱形继承的问题是什么?
    菱形继承是指在继承关系中存在一种特殊的结构,其中一个派生类同时继承两个基类,而这两个基类又共同继承同一个基类。这样形成的继承关系呈菱形,因此得名菱形继承。
  2. 什么是菱形虚拟继承?如何解决数据冗余和二义性的
    菱形虚拟继承是为了解决菱形继承中的数据冗余和函数二义性问题而引入的机制。通过使用虚拟继承(virtual),可以确保在菱形继承中共享基类的实例,从而避免了数据冗余的问题。
  3. 继承和组合的区别?什么时候用继承?什么时候用组合?
  • 继承(Inheritance)和组合(Composition)是面向对象编程中用于构建类之间关系的两种主要方式。

  • 继承是一种"is-a"关系,其中一个类可以继承另一个类的属性和行为。通过继承,子类可以共享父类的成员变量和成员函数,并且可以添加自己的特定功能。继承适用于具有层次结构的类,其中子类是父类的特殊化。

  • 组合是一种"has-a"关系,其中一个类包含另一个类的对象作为成员变量。通过组合,一个类可以使用其他类的对象来实现自己的功能,而不需要继承其所有特性。组合适用于在一个类中使用其他类的功能,而不需要与其形成层次结构。

  • 当需要表示一种类与类之间的层次结构、子类是父类的特殊化关系时,可以使用继承。继承可以提供代码重用和多态性的好处。当需要在一个类中使用另一个类的功能、将一个类作为另一个类的组成部分时,可以使用组合。组合可以实现代码模块化和灵活性。

  • 在选择继承或组合时,需要考虑类之间的关系和需求。如果存在"is-a"关系,且子类可以完全继承父类的属性和行为,可以选择继承。如果存在"has-a"关系,且一个类需要使用另一个类的功能,可以选择组合。此外,还应考虑代码的可维护性、扩展性和设计的灵活性。
    (本章完)

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

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

相关文章

计算机算法分析与设计(15)---贪心算法(虚拟汽车加油问题和最优分解问题)

文章目录 一、虚拟汽车加油问题1.1 问题描述1.2 思路分析1.3 代码编写 二、最优分解问题2.1 问题描述2.2 思路分析2.3 代码编写 一、虚拟汽车加油问题 1.1 问题描述 一辆虚拟汽车加满油后可行驶 n n n km。旅途中有若干加油站。设计一个有效算法&#xff0c;指出应在哪些加油…

【STL】bitset位图的介绍和使用

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C进阶 ⭐代码仓库&#xff1a;C进阶 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们的支持是我…

优思学院|精益管理涵盖哪些内容?

精益生产管理涵盖哪些内容&#xff1f;精益生产是一种以客户需求为引导、以消除浪费和持续改进为核心的生产管理模式&#xff0c;有效提升了公司的效率和利润&#xff0c;投入却极少。它包含哪些具体要素呢&#xff1f; 准时化生产&#xff08;JIT&#xff09; JIT&#xff0…

idea调教-全键盘操作

先转个vim&#xff0c;现在代码编辑可以使用全部键盘 接下来键盘使用目录 现在需要在项目文件中进行跳转&#xff0c;idea在左边目录等进行切换使用alt1等可以切换左右目录等&#xff0c;用方向建可以选中对应的文件&#xff0c;使用shiftenter可以在右边打开新的标签页,使用a…

日常--windows11右键切换回win10

文章目录 一&#xff0e;前言二&#xff0e;方法1.一键切换2.恢复回Win11右键菜单&#xff1a; 一&#xff0e;前言 从win10更新成win11后&#xff0c;很多地方不适应&#xff0c;这里演示如何将windows11右键切换回win10 二&#xff0e;方法 1.一键切换 winr打开运行 输入…

C++ 友元函数和友元类

前言 在本文中&#xff0c;您将学习在C 中创建友元函数和友元类&#xff0c;并在程序中有效地使用它们。OOP的重要概念之一是数据隐藏&#xff0c;即非成员函数无法访问对象的私有或受保护的数据。但是&#xff0c;有时这种限制可能迫使程序员编写冗长而复杂的代码。因此&#…

反向传播back propagation

深度学习概述 决定要怎么连接这些neuron的时候 就已经确定了function set 相比于之前做logistic regression&#xff0c;linear regression的时候&#xff0c;换一个方式来决定function set 比较大&#xff0c;包含了logistic regression&#xff0c;linear regression没法包含…

【C++入门 一 】学习C++背景、开启C++奇妙之旅

目录 1.什么是C2. C的发展史3. C的重要性3.1 语言的使用广泛度3.2 在工作领域1. 操作系统以及大型系统软件开发2. 服务器端开发3. 游戏开发4. 嵌入式和物联网领域5. 数字图像处理6. 人工智能7. 分布式应用 3.3 在校招领域3.3.1 岗位需求3.3.2 笔试题 4. 如何学习C4.1 别人怎么学…

工业电子中的深力科分享一款PWM控制器 KA3525A

关于PWM控制器&#xff1a; PWM控制器是一种用于控制电机或其他设备的电路&#xff0c;它通过改变脉冲宽度调制&#xff08;PWM&#xff09;信号的占空比来控制设备的输出。PWM控制器可以使用单片机或开发板等设备来实现&#xff0c;通过设定占空比&#xff0c;可以轻松地控制…

LeetCode —— dfs和bfs

797. 所有可能的路径 给你一个有 n 个节点的 有向无环图&#xff08;DAG&#xff09;&#xff0c;请你找出所有从节点 0 到节点 n-1 的路径并输出&#xff08;不要求按特定顺序&#xff09;。 graph[i] 是一个从节点 i 可以访问的所有节点的列表&#xff08;即从节点 i 到节点…

【斗罗二】天梦哥告白冰帝,唐三再返场,雨浩通过冰帝考验,觉醒新武魂

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析斗罗大陆2绝世唐门国漫资讯。 斗罗大陆动画第二部绝世唐门第19集已经更新了&#xff0c;全都是霍雨浩与天梦哥在极北之地&#xff0c;吸引冰帝加入造神计划的过程。不仅有天梦哥的爱情宣言告白&#xff0c;唐三也再次限时…

设计模式_备忘录模式

备忘录模式 介绍 设计模式定义案例问题堆积在哪里解决办法备忘录模式行为型模式&#xff0c; 保存了数据某一个时间点的状态 在需要的时候进行回档单机游戏的角色 数据保存并且回档保存和回档加一个状态管理类 类图 代码 MomentData using UnityEngine;public class MomentD…

SLAM从入门到精通(从仿真到实践)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 之前花了40多篇文章&#xff0c;弄清了什么是slam&#xff0c;怎么学习slam&#xff0c;什么是ros&#xff0c;怎么利用ros来学好slam等等。不仅如…

云安全(1)--初识容器逃逸之特权容器逃逸

文章目录 前言privileged,特权容器逃逸环境配置实际利用实际环境利用计划任务/var/spool/cron/crontabs/ 适用于ubuntu debain/var/spool/cron 适用于centos ld.so.preloadssh 前言 在10.15号的上海中华武数杯的渗透赛里做到了一个k8s的题目&#xff0c;这应该是我第一次在比赛…

13.3测试用例进阶

一.测试对象划分 1.界面测试(参考软件规格说明书和UI视觉稿) a.什么是界面 1)WEB站(浏览器) 2)app 3)小程序 4)公众号 b.测试内容 1)界面内容显示的一致性,完整性,准确性,友好性.比如界面内容对屏幕大小的自适应,换行,内容是否全部清晰展示. 2)验证整个界面布局和排版…

【数据结构】线性表(七)堆栈:链式栈及其基本操作(初始化、判空、入栈、出栈、存取栈顶元素、清空栈);顺序栈与链式栈之比较

文章目录 一、堆栈1. 定义2. 基本操作 二、顺序栈三、链式栈0. 链表1. 头文件和常量2. 栈结构体3. 栈的初始化4. 判断栈是否为空5. 入栈6. 出栈7. 存取栈顶元素8. 清空栈9. 主函数10. 代码整合 四、 顺序栈与链式栈的比较 堆栈&#xff08;Stack&#xff09;和队列&#xff08;…

Linux MMC子系统 - 1.eMMC简介

By: Ailson Jack Date: 2023.10.21 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/160.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

JAVA基础-数据类型(2)

目录 1、基本数据类型2、引用数据类型3、类型默认值4、数据类型的转换4.1、自动类型转换4.2、强制类型转换4.3、隐含强制类型转换 1、基本数据类型 :::tips Java语言提供了八种基本类型。六种数字类型&#xff08;四个整数型&#xff0c;两个浮点型&#xff09;&#xff0c;一…

C++多重、多层、分层继承

在本文中&#xff0c;您将学习C 编程中的不同继承模型&#xff1a;带有示例的多继承&#xff0c;多层和分层继承。 继承是面向对象编程语言的核心功能之一。它允许软件开发人员从现有的类派生一个新的类。派生类继承基类&#xff08;现有类&#xff09;的功能。C 编程中有多种…

逗号表达式

#include<stdio.h> int cmp() {return(2,1); } int main() {int z cmp();printf("%d",z);return 0; } 逗号表达式括号里的优先级是自左向右&#xff0c;最后一个值为最终的结果。