C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

这篇具有很好参考价值的文章主要介绍了C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++的一个大坑:菱形继承 希望这篇文章能让你理解什么是菱形继承,以及菱形继承的注意事项


单继承与多继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
 java语言不支持多继承,只支持单继承。

菱形继承:菱形继承是多继承的一种特殊情况

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

菱形继承会导致什么呢?

菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Child的对象中Person成员会有两份

比如:

class Person
{
public:
	string _name; // 姓名
};
class Student : public Person
{
protected:
	int _num; //学号
};
class Teacher : public Person
{
protected:
	int _id; // 职工编号
};
class Child : public Student, public Teacher
{
protected:
	string _obj; // 主修项目
};

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

	Child obj;
	obj._name;
	//从空间上说是数据冗余、从访问角度上是二义性

运行结果是:C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
如果想要代码跑起来可以这样:指定类域去访问

	Child obj;
	obj.Student::_name = "张三";
	obj.Teacher::_name="张老师";

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”


虚拟继承

但是上述做法从根本上并没有解决数据二义性的问题,为了能够解决二义性,C++又引入了一个坑,虚拟继承。(在继承的类派生列表的访问说明符前加上virtual)

class Person
{
public:
	string _name; // 姓名
};
class Student : virtual public Person
{
protected:
	int _num; //学号
};
class Teacher : virtual public Person
{
protected:
	int _id; // 职工编号
};
class Child : public Student, public Teacher
{
protected:
	string _obj; // 主修项目
};

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

  虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用

  为了更清楚的明白菱形继承与菱形虚拟继承的关系,我们通过使用内存监视窗口来了解其数据存储方式(监视窗口编译器优化过,不是原汁原味了):
C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

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;
};

我们先使用内存窗口观察菱形继承在内存中的存储状况:

	D d;
	d._b = 1;
	d._c = 2;
	d._d = 3;
	d.B::_a = 4;
	d.C::_a = 5;

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
菱形虚拟继承在内存中的分布情况:

	D d;
	d._b = 1;
	d._c = 2;
	d._d = 3;
	d.B::_a = 4;
	d.C::_a = 5;
	d._a = 6;

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
我们对最后的地址分析:(内存地址跟上图不一样是因为重新运行了一次)
C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
这个虚基表是用来干什么的?
C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”
菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A

下面是上面的Person关系菱形虚拟继承的原理解释:
C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”


如有错误或者不清楚的地方欢迎私信或者评论指出🚀🚀文章来源地址https://www.toymoban.com/news/detail-436081.html

到了这里,关于C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++三大特性之一:继承

    C++三大特性:继承、多态和封装。继承是面向对象编程的一个核心概念,它允许我们根据一个已存在的类(基类或者叫父类),创建一个新的类(派生类或者叫子类),这个新的类继承了类的属性和行为。 1.继承格式。 class 子类名 :继承属性(publicprotectedprivate)父类名{

    2024年04月25日
    浏览(18)
  • C++ 面向对象三大特性——继承

    ✅1主页:我的代码爱吃辣 📃2知识讲解:C++ 继承 ☂️3开发环境:Visual Studio 2022 💬4前言:面向对象三大特性的,封装,继承,多态,今天我们研究研究 C++的继承 。 目录 一.继承的概念及定义 1.继承的概念  2.继承的定义 二. 继承关系和访问限定符  三.基类和派生类对象赋

    2024年02月12日
    浏览(37)
  • 【C++】三大特性 --- 继承的详细讲解

    目录 1.继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6.继承与静态成员 7.复杂的菱形继承及菱形虚拟继承 8.继承的

    2024年02月05日
    浏览(33)
  • 面向对象的三大特性之继承(C++)

    概念   继承机制是面向对象编编程使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承是类设计层次的复用。 定

    2024年02月06日
    浏览(38)
  • 【继承】复杂的菱形继承

    博主首页:  有趣的中国人   专栏首页:  C++进阶   本篇文章主要讲解 菱形继承   的相关内容 目录 1. 继承与友元 2. 继承与静态成员 3. 复杂的菱形继承及菱形虚拟继承 3.1 继承分类 3.2 菱形继承导致的问题 3.3 虚拟继承解决数据冗余的原理 4. 继承和组合的区别 友元关系不

    2024年04月22日
    浏览(23)
  • C++核心编程—类和对象,类的三大特性——封装、继承、多态

    纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。 ①什么是对象? 生活中有各种各样的 事物 ,如人、动物、植物等在C++中将这些称为对象。 对象多种多样, 各种对象的属性也不相同 。 例如狗的品种,毛色,年龄等 各个对象都有自己的行为 ,例

    2024年02月07日
    浏览(47)
  • 【C++庖丁解牛】面向对象的三大特性之一多态 | 抽象类 | 多态的原理 | 单继承和多继承关系中的虚函数表

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 需要声明的,本节课件中的代码及解释都是在vs2013下的x86程序中,涉及的指针都是4bytes。如果要其他平台

    2024年04月10日
    浏览(40)
  • 【C++】继承的基本特性(定义,赋值转换,友元,静态成员,虚拟继承,默认成员函数,作用域)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。 Person是父类,也称作基类。Student是子类,也称作派生类 总结: 基类private成员

    2024年02月14日
    浏览(32)
  • C++:面向对象大坑:菱形继承

    单继承:一个子类只有 一个直接父类 时称这个继承关系为单继承。 图示: 多继承:一个子类有 两个或以上直接父类 时称这个继承关系为多继承。 图示: 1.概念 菱形继承:菱形继承是多继承的一种特殊情况。即:一个类是另外几个类的子类,而这几个子类又是另外一个类

    2024年04月27日
    浏览(27)
  • java三大特性之【继承】

    概念 继承就是将多个类的共性抽取出来,提出继承的概念。就是在进行共性抽取,实现代码复用。 提高代码的复用性,方便进行子类,子功能的扩展,将所有共性的内容放在父类(基类),子类只需要关注子类独有的属性和功能 父类和子类成员关系 父类和子类不存在同名的

    2024年02月08日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包