复杂的菱形继承及菱形虚拟继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承 菱形继承:菱形继承是多继承的一种特殊情况。...这时就需要使用虚拟继承: 此时,_name就只有一份了。 注意:virtual是加在腰部的类的。 虚拟继承可以解决菱形继承的二义性和数据冗余的问题。...如上面的继承关系,在Student和 Teacher的继承Person时使用虚拟继承,即可解决问题。...虚拟继承解决数据冗余和二义性的原理 我们给出了一个简化的菱形继承继承体系,再借助内存窗口观察对象成员的模型 class A { public: int _a; }; class B : public..._d = 5; return 0; } 下图是菱形继承的内存对象成员模型: 下图是菱形虚拟继承的内存对象成员模型: D对象中将A放到的了对象组成的最下面,这个A同时属于B和C。
1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继 承自类A,因此在类D中两次出现类A中的变量和函数。...为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。...,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用,而一旦离开了多重继承,虚拟继承就完全失去了存在的必要因为这样只会降低效率和占用更多的空间。...虚拟继承与普通继承不同的是,虚拟继承可以防止出现diamond继承时,一个派生类中同时出现了两个基类的子对象。也就是说,为了保证 这一点,在虚拟继承情况下,基类子对象的布局是不同于普通继承的。...所以必须把父类的所有变量都继承下来,这样既能保护父类的变量也能使用父类的函数。 6.C++虚拟继承的实际大小 输出下面class的大小: [cpp] view plaincopyprint?
金句分享: ✨如果事事都如意,那就不叫生活了.✨ 前言 C++中多继承是指一个子类可以从多个父类中继承属性和行为. 其中涉及菱形继承和虚拟继承,显得复杂很多. 需要理解原理....单继承: C++中的单继承是指一个子类只能继承一个父类的特性。...单继承的好处在于它可以保证类之间的关系更加清晰和简单,并且可以减少代码的冗余和复杂度。 多继承: 在C++中,多继承是指当一个类继承自多个父类时的继承方式。..._d = 10; return 0; } 虚拟继承:解决数据冗余和二义性的原理....C++语法十分复杂,多继承,菱形继承就是一种体现. 由于多继承和菱形继承的复杂性,后来的很多语言就跳过了这个大坑,比如隔壁Java.
摘要 本文系统讲解了 C++ 中的继承机制,包括单继承、多继承、菱形继承及虚拟继承,配合图解和代码示例直观展示各类继承的对象模型、内存布局及访问特点,重点说明虚拟继承如何通过共享基类实例、虚基表偏移和构造顺序...——》使用虚拟继承! 以上述对象模型为例,在 Teacher 和 Athlete 继承 Person 时采用虚拟继承,即可避免 Student 同时拥有两份 Person 子对象。...虚拟继承是一种专门用于解决菱形继承问题的机制,在其它普通继承场景下不建议使用。...在 C++ 中,虚拟继承的使用方式是:当多个派生类继承自同一个公共基类,并且这些派生类又被同一个子类多继承时,应当在这些“中间层”父类继承公共基类的地方,使用 virtual 关键字进行修饰。...总结 C++ 继承方式灵活多样,单继承简单直观,多继承可组合功能但可能出现二义性,而菱形继承会导致数据冗余和访问冲突;虚拟继承通过共享基类实例和虚基表机制有效解决菱形继承问题,同时调整构造顺序保证基类唯一初始化
需要注意的是,虚拟继承不要在其他地方去使用。...例如: class Person { public: string _name; // 姓名 }; // 虚拟继承 ———————————— (在接受同一个信息的两个子类上进行虚拟继承) class...七、继承的总结和反思 1、很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱 形继承就有菱形虚拟继承,底层实现就很复杂。...菱形继承是指在C++中使用多重继承时,出现了多个派生类继承同一个基类,而最终有一个类同时继承了这些派生类,形成了一个菱形的继承结构。 ②数据冗余和二义性。 (2)什么是菱形虚拟继承?...①为了解决数据冗余和二义性问题,C++提供了虚继承的机制。通过在中间派生类的继承声明中加上关键字virtual,将共同继承的基类标记为虚拟继承。
: virtual public Person //virtual虚拟继承在腰部 { protected: int _num; //学号 }; class Teacher : virtual public...虚继承解决方案 菱形继承——多继承延伸的坑 多继承不是问题,多继承实现的菱形继承才是问题 因此设计了“菱形虚拟继承”来解决,下面我们会介绍虚继承 4.2.4 虚继承机制与virtual关键字 关键词...,因为菱形虚拟继承以后,无论是使用还是底层都会复杂很多。...当然有多继承语法支持,就一定存在会设计出菱形继承,像Java是不支持多继承的,就避开了菱形继承 4.3 IO库中的菱形虚拟继承 4.4 多继承中的指针偏移问题 4.4.1 题目 class Base1...// string _name; // 姓名 //}; //// //class Student : virtual public Person //virtual虚拟继承在腰部 //{ //protected
那为了更好的解决菱形继承导致的数据冗余和二义性的问题,C++就引入了虚拟继承… 3.2 解决方法——虚拟继承 C++引入了虚拟继承可以解决菱形继承的二义性和数据冗余的问题 那虚拟继承是怎样的呢?...虚拟继承要用到一个新的关键字——virtual(虚拟的) 那怎么做呢? 给继承关系中第二层的类增加一个关键字virtual就行了。 然后就可以了吗?...虚拟继承可以解决菱形继承的二义性和数据冗余的问题。 如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。...3.3 虚拟继承的原理 为了研究虚拟继承的原理,我们下面给出一个简化的菱形继承的继承体系,再借助内存窗口(因为监视窗口已经看不出来底层真实的样子了)观察对象成员的模型 现在我们给出这样一个继承体系: class...继承的反思和总结 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。
:多继承中的菱形陷阱与虚继承破解之道 前情提示:多继承会是一个坑!!!...4.1 类的不同“血缘”关系:单继承与多继承 所谓单继承就是:一个派生类只有一个直接基类时称这个继承关系为单继承 //单继承 class Person { protected: int _age;...:一个派生类有两个或者两个以上直接基类时称这个继承关系为多继承,多继承对象在内存中的模型是,先继承的基类在前面,后面继承的基类在后面,派生类成员放在最后面。...我们可以设计出多继承,但是不建议设计出菱形继承,因为菱形虚拟继承以后,无论是使用还是底层都会复杂很多。当然有多继承语法支持,就⼀定存在会设计出菱形继承,像Java是不支持多继承的,就避开了菱形继承。...= p3 先继承的父类在上面,后继承的父类在下面,最后才是子类的!!! 4.2 IO库中的菱形虚拟继承 其实库中是有菱形继承的(现实中不要玩菱形继承!!!)
1.多重继承带来的问题 C++虚拟继承一般发生在多重继承的情况下。C++允许一个类有多个父类,这样就形成多重继承。...虚拟继承就是解决这个问题的,通过把继承关系定义为虚拟继承,在构造EGStudent类对象的时候,EGStudent类的祖先类Person的对象只会被构造一次,这样就可以避免存在多个IDPerson和Name...(2)被虚拟继承的基类,叫做虚基类。虚基类实际指的是继承的方式,而非一个基类,是动词,而非名词。 (3)为了实现虚拟继承,派生类对象的大小会增加4。...这个增加的4个字节,是因为当虚拟继承时,无论是单虚继承还是多虚继承,派生类需要有一个虚基类表来记录虚继承关系,所以此时子类需要多一个虚基类表指针,而且只需要一个即可。...因为虚拟继承只是表名某个基类的对象在派生类对象中只被构造一次,而在本例中类Student和Employee对象在EGStudent对象中本来就不会被构造多次,所以不将它们申明虚基类也是完全可以的。
本文将从菱形继承的问题出发,对虚拟继承的底层实现原理进行深入剖析,结合代码示例和内存模型分析,带你彻底理解这一 C++ 进阶知识点。下面就让我们正式开始吧!...二、虚拟继承:菱形继承的解决方案 2.1 虚继承的语法规则 虚继承的使用非常简单,只需在继承时添加virtual关键字,指定对公共基类的继承为虚继承。...但虚继承是如何实现这一效果的呢?其底层内存模型发生了怎样的变化呢? 三、菱形虚拟继承的底层实现原理 要理解虚继承的原理,必须深入分析其内存模型。...3.1 简化的菱形虚拟继承模型 为了便于观察内存布局,我们使用更简单的数据类型(int)替代复杂类型(string),构建简化的菱形虚拟继承体系: class A { public:...包含虚函数的类对象有 vptr,虚继承的中间子类对象有 vbptr。 6.4 菱形虚拟继承中的虚函数重写 如果菱形虚拟继承体系中包含虚函数,重写规则与普通继承一致,但内存模型会更复杂。
数据冗余:如下图所示,Person有两个—— 二义性:访问不明确~>指定类域勉强解决 7.2.3 虚继承解决方案 菱形继承——多继承延伸的坑 多继承不是问题,多继承实现的菱形继承才是问题。...因此设计了“菱形虚拟继承”来解决,下面我们会介绍虚继承。 7.2.4 虚继承机制与virtual关键字 关键词virtual加在腰部位置,如下图所示—— 都加上virtual可不可以?...,不建议设计出菱形继承 我们可以设计出多继承,但是不建议设计出菱形继承,因为菱形虚拟继承以后,无论是使用还是底层都会复杂很多。...当然有多继承语法支持,就一定存在会设计出菱形继承,像Java是不支持多继承的,就避开了菱形继承。...7.3 IO库中的菱形虚拟继承 7.4 多继承中的指针偏移问题 7.4.1 题目 下面说法正确的是( ) A. p1 == p2 == p3 B. p1 < p2
前面提到过,解决菱形继承产生的数据二义性问题和数据冗余,就需要用到虚拟继承,关于它是如何解决的,我们来一起研究。..._name = "peter"; } 原理 为了研究虚拟继承原理,我们给出了一个简化的菱形继承继承体系,再借助内存窗口观察对象成 员的模型。...下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下 面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指 向的一张表。...很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱 形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。...不过继承也有用武之地的,有 些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用 继承,可以用组合,就用组合。
前言: 在前面,我们已经讲过继承的相关知识,今天我们来将一个由继承拓展出来的很重要的知识,那就是——菱形继承和虚拟继承及相关知识讲解 一、单继承和多继承 C++单继承 在C++中,单继承是指一个类只能继承自一个基类...C++多继承 多继承允许一个类继承自多个基类。这意味着派生类可以有多个直接的基类。...多继承的复杂性 多继承虽然功能强大,但也带来了一些复杂性,例如菱形继承问题。...菱形继承很容易带来冗余性和二义性,这些就需要我们用虚拟继承来解决,这些问题挺重要,我们往下看 二、菱形继承 C++中的菱形继承是指在类的继承关系中,存在两个或更多个直接或间接的基类,它们之间形成了一个类似菱形的结构...下面我们来讲解一种解决上面问题的方法——虚拟继承 三、虚拟继承 虚继承是一种特殊的继承方式,用于解决菱形继承中的冗余性和二义性问题。了解虚继承的相关知识点有助于更好地使用它。
图文例解C++类的多重继承与虚拟继承 在过去的学习中,我们始终接触的单个类的继承,但是在现实生活中,一些新事物往往会拥有两个或者两个以上事物的属性,为了解决这个问题,C++引入了多重继承的概念...以上面的代码为例,我们要想让AmphibianCar类既获得一个Vehicle的拷贝,而且又同时共享用Car类与Boat类的数据成员与成员函数就必须通过C++所提供的虚拟继承技术来实现。 ...我们在Car类和Boat类继承Vehicle类出,在前面加上virtual关键字就可以实现虚拟继承,使用虚拟继承后,//站点:www.cndev-lab.com //所有稿件均有版权,如要转载,...ShowMe() = 0; protected: int weight; }; class Car:virtual public Vehicle//汽车,这里是虚拟继承...虽然说虚拟继承与虚函数有一定相似的地方,但读者务必要记住,他们之间是绝对没有任何联系的!
; ③一个类不能派生其自身,原因和②是相同的 三、继承的基本特点 ①一个类可以被多个类继承 ②一个类也可以继承于多个类 四、单一继承 一个类只继承于一个类叫做单一继承 class A { }; class...B :public A //单一继承 { }; 五、多重继承 一个类只继承于多个类叫做多重继承 class A{}; class B {}; class C :public B, public...A //多重继承 { }; 六、多级继承 一个子类还可以作为另一个类的父类而派生出另一个子类。...最后一个类D又继承于B和C,这样形式的继承称为菱形继承 菱形继承的缺点: 数据冗余:在D中会保存两份A的内容 访问不明确(二义性):因为D不知道是以B为中介去访问A还是以C为中介去访问A,因此在访问某些成员的时候会发生二义性...虚继承的作用:为了保证公共继承对象在创建时只保存一分实例 虚继承解决了菱形继承的两个问题: 数据冗余:顶级基类在整个体系中只保存了一份实例 访问不明确(二义性):可以不通过作用域访问符::来调用(原理就是因为顶级基类在整个体系中只保存了一份实例
一、继承简介 1、继承概念 继承 是 面向对象 特性之一 , ( 封装 - 继承 - 多态 ) 继承 可以 令一个类 从 另一个类 中 继承 该类的 属性 和 方法 , 继承 属性 和 方法 的类被称为..." 子类 " , 被 继承 的类 称为 " 父类 " 或 " 基类 " ; 2、继承语法 继承语法 : class 子类类名(父类类名): 子类内容 父类类名 是 已经存在的 父类 或 基类 的名称...; 子类类名 是 本次新创建的类类名 ; 该 子类 继承了 父类 所有的 成员属性 和 成员方法 ; 3、单继承与多继承 单继承 指的是 一个子类 继承 一个父类 ; 多继承 指的是 一个子类 继承...多个父类 ; 多继承语法 : class 子类类名(父类类名1, 父类类名2, .... , 父类类名n): 子类内容 二、代码示例 1、代码示例 - 单继承 父类 Animal 描述动物 , 只有...Process finished with exit code 0 2、代码示例 - 多继承 定义两个父类 : Animal 和 Walk ; class Animal: def __init
一、多继承 1、多继承基本语法 多继承 概念 : 一个 子类 ( 派生类 ) 可以 继承 多个 父类 ( 派生类 ) ; 一个类可以继承多个类的属性和方法 ; 使用多继承 , 可以创建更复杂的类 ,...该派生类可以组合多个基类的功能 ; 只有 C++ 语言有多继承概念 , 别的语言没有该概念 ; Java 语言只能继承一个父类 , 可以实现多个接口 ; 多继承语法 : class 子类名称 : 访问控制关键字...访问控制关键字 父类名称n { // 子类内容 } 访问控制关键字 : public : 表示 公有继承 ; protected : 表示 保护继承 ; private : 表示 私有继承 ; 继承的...每个 父类 都可以指定一个 访问控制关键字 ; 2、多继承子类构造初始化 调用多个父类构造函数 : 如果一个 子类 ( 派生类 ) 继承多个 父类 ( 基类 ) , 使用 初始化列表 调用 多个 父类...可以直接访问 ; 成员变量 名称 相同 , 就需要使用 父类 :: 成员变量名 或 爷爷类 :: 成员变量名 进行访问 ; 二、多继承案例 ---- 1、代码示例 - 简单多继承案例 在下面的代码中 ,
Javascript继承通常有三种方式。...console.log(this.age); }; var instancel = new SubType("Nicholas", 12); SuperType() 该继承通过构造函数继承原型链的方法和父类的属性...,但该方法会有两次调用父类,第一次是在继承原型链,第二次在继承属性。...第二种:原型链继承 //原型式继承实例代码: function createObj(o) {//对传入的对象执行了一次浅复制 function F() {} F.prototype...第三种:寄生式继承 在第一种的方法上,我们在第一次调用父类,也就是继承原型的时候,实际上只需要父类的原型副本,那么取得副本,也就省去了这一次调用。 该继承技术是最常用的。
什么是菱形继承?菱形继承的问题是什么? 菱形继承:菱形继承是多继承一种特殊的继承方式。如下如所示为一菱形继承 ? 即两个派生类继承同一个基类,同时两个派生类又作为基本继承给同一个派生类。...什么是菱形虚拟继承?如何解决数据冗余和二义性的? 虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。...需要注意的是,虚拟继承不要在其他地方去使用。..._name = "peter"; } 虚拟继承解决数据冗余和二义性的原理 class A { public: int _a; }; // class B : public A class B...下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。
7.复杂的菱形继承及菱形虚拟继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承 ? 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承 ?...需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决 a.Student::_name = "xxx"; a.Teacher::_name = "yyy"; } 虚拟继承可以解决菱形继承的二义性和数据冗余的问题...如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。...下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。...不过继承也有用武之地的,有些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用继承,可以用组合,就 用组合。