首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++之继承相关问题——菱形继承&继承

什么是菱形继承?菱形继承问题是什么? 菱形继承:菱形继承是多继承一种特殊继承方式。如下如所示为一菱形继承 ? 即两个派生类继承同一个基类,同时两个派生类又作为基本继承给同一个派生类。...这种继承形如菱形,故又称为菱形继承。 菱形继承问题:菱形继承主要有数据冗余和二义性问题。...由于最底层派生类继承了两个基类,同时这两个基类有继承是一个基类,故而会造成最顶部基类两次调用,会造成数据冗余及二义性问题。如下图所示,在Assistant对象中Person成员会有两份。 ?...什么是菱形虚拟继承?如何解决数据冗余和二义性? 虚拟继承可以解决菱形继承二义性和数据冗余问题。如上面的继承关系,在Student和Teacher继承Person时使用虚拟继承,即可解决问题。...下图是菱形虚拟继承内存对象成员模型:这里可以分析出D对象中将A放到了对象组成最下面,这个A同时属于B和C,那么B和C如何去找到公共A呢?这里是通过了B和C两个指针,指向一张表。

6.6K41
您找到你想要的搜索结果了吗?
是的
没有找到

【Example】C++ 虚基类与虚继承 (菱形继承问题)

C++ 是支持多继承语言,但是实际项目开发中非必要请避免使用多继承以降低代码逻辑复杂性。 当然 C++ 多继承特性带来一些问题即菱形继承。 ?...根据 C++ 类继承机制,子类大小=父类大小+子类自身成员大小。...所以在 Blu 类中仍然存在菱形继承问题,所有需要将所有继承同一基类上级父类继承方式声明为 virtual。...:【Example】C++ 虚基类与虚继承 (菱形继承问题) 虚继承时,子类内存结构当中不包含父类。...【Example】C++ 接口(抽象类)概念讲解及例子演示 【Example】C++ 虚基类与虚继承 (菱形继承问题) 【Example】C++ Template (模板)概念讲解及编译避坑 【Example

86630

继承问题

要点一 首先确定好确定好哪个类作为父类,哪个类作为子类,同时要让父类所有能够进行继承属性前加上public public class Shape { Shape(){} public void S()...L(){}} 要点二 子类需要在首行最外层类名后加上extends + 父类名 public class Circle extends Shape{·····} 要点三 在子类添加属性,要加上需要继承父类属性并且...super(继承属性) BeiJingPeople(String name,int age,String sex,String sno){ super(name,age,sex); this.sno =...sno;} 结语 继承属于Java编程语言最基础东西,是需要我们不断练习,其中还具有许多细节都需要注意,其中我认为最容易忘记细节就是在子类中继承父类时,子类名后面加上extends+父类名细节

7210

C++继承(多继承、菱形继承?)

菱形继承问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性问题。在 Assistant 对象中 Person 成员会有两份。...C++不能容忍数据冗余和二义性,于是提出了一个解决方案: 虚继承(virtual) 2.通过虚继承解决菱形继承问题 方案:在类腰部位置加一个 virtual 关键字: 注意: 虚继承 virtual...再配合刚刚我们讲指定作用域,二义性也可以得到很好解决。 那么问题来啦,C++编译器是如何通过虚继承解决数据冗余和二义性呢?...❓ 问题: 有童鞋会有疑问为什么 D 中 B 和 C 部分要去找属于自己 A?那么大家看看当下面的赋值发生时,d 是不是要去找出 B/C 成员中 A 才能赋值过去?...否则在复杂度及性能上都有问题。 多继承可以认为是C++缺陷之一,很多后来OO语言都没有多继承,如Java。

1.9K20

C++继承继承语法与菱形继承

继承语法 C++允许一个类继承多个类 语法: class 子类 :继承方式 父类1 , 继承方式 父类2......Son() { m_C = 300; m_D = 400; } public: int m_C; int m_D; }; //多继承容易产生成员同名情况 //通过使用类名作用域可以区分调用哪一个基类成员...,子类使用时候要加作用域 菱形继承 菱形继承概念: ​ 两个派生类继承同一个基类 ​ 又有某个类同时继承者两个派生类 ​ 这种继承被称为菱形继承,或者钻石继承 典型菱形继承案例: 菱形继承问题:...羊继承了动物数据,驼同样继承了动物数据,当草泥马使用数据时,就会产生二义性。...使用了虚继承后对比未使用虚继承解决菱形继承 总结: 菱形继承带来主要问题是子类继承两份相同数据,导致资源浪费以及毫无意义 利用虚继承可以解决菱形继承问题

68310

C#继承_继承关系中继承

大家好,又见面了,我是你们朋友全栈君。 继承详解: 一.继承概念: 二....基类和派生类: 三.继承作用: 四.继承特点: 五.一般写法: 六.举例说明: 七.继承注意事项: 一.继承概念: 继承:是面向对象程序设计中最重要概念之一。...三.继承作用: 使程序创建和维护变得很容易; 有利于代码重用和节省时间; 编写时候可以更快理解和应用; 四.继承特点: 继承了基类/父类属性和方法,子类可以继承父类继承属性、函数; 继承时并非完全继承...,只有可继承类成员才可以被继承,主要使用访问修饰符进行设置; 继承实质上是对象与对象之间关系; C#继承只能实现单继承,每个类只能继承一个父类,一个父类可以拥有多个子类; 继承可以隔代继承,也就是子类下面还可以有子类...; 不允许相互继承(循环继承); C#不允许多重继承,但是可以实现多重接口继承; 五.一般写法: class { ... } class :

54930

C++】继承 ⑬ ( 虚继承原理 | 虚继承解决继承二义性问题 | 二义性产生原因分析 )

一、虚继承原理 1、虚继承解决继承二义性问题 继承二义性 : 如果 一个 子类 ( 派生类 ) 继承多个 父类 ( 基类 ) , 这些父类 都继承了 相同父类 , 那么 子类 访问 父类父类 中成员..., 就会产生 二义性 ; 报错 : error C2385: 对“x”访问不明确 ; 使用 " 虚继承 " 可以解决上述问题 , 子类 继承父类时 , 在 访问限定符 之前使用 virtual 关键字..., 即可将 普通继承 改为 虚继承 ; 下面的代码中 A 是父类 ; B 类 和 C 类 虚继承 A 类 , 这样当 某个类 同时 多继承 B 类 和 C 类时 , 访问 A 类中成员时 , 不会出现...public: int z; }; // D 多继承 B 和 C // 分别从 B 和 C 各自继承一个来自 A 成员 x class D : public B, public C { public...对象调用 , 一次由 C 对象调用 ; 此时 D 对象中就包含了 两个 A 类 子对象 ; 当 访问 A 类成员时 , 不知道访问哪个 A 类成员 , 就出现了二义性 ; 3、虚继承原理 使用 虚继承

21020

C++中继承

,但是会存在越界访问问题 //ps2->_No = 10; } 继承作用域 在继承体系中基类和派生类都有独立作用域。...因为从菱形继承下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性问题。在Assistant对象中Person成员会有两份。..._name = "peter"; // 需要显示指定访问哪个父类成员可以解决二义性问题,但是数据冗余问题无法解决 a.Student::_name = "xxx"; a.Teacher::_name...= "yyy"; } 而为了解决我们数据冗余问题我们就想出来一个办法: 虚拟继承可以解决菱形继承二义性和数据冗余问题。...如上面的继承关系,在Student和Teacher继承Person时使用虚拟继承,即可解决问题。需要注意是,虚拟继承不要在其他地方去使用,只有在菱形继承时使用。

7110

C++【继承

,即支持一个子类继承多个父类,使其基础信息更为丰富,但凡事都有双面性,多继承 在带来巨大便捷性同时,也带来了个巨大坑:菱形继承问题 注:其他面向对象高级语言为了避免出现此问题,直接规定了不允许出现多继承...而且还没有解决数据冗余问题 真正解决方法:虚继承 注:虚继承是专门用来解决 菱形继承 问题,与多态中虚函数没有直接关系 虚继承:在菱形继承腰部继承父类时,加上 virtual 关键字修饰被继承父类..._name << endl; return 0; } 此时可以解决 菱形继承 数据冗余 和 二义性 问题继承是如何解决菱形继承问题?...虚继承相关知识补充 虚继承底层是如何解决菱形继承问题?...,最后还学习了多继承模式中容易引发菱形继承问题,探究了其原因及解决方法,关于继承是如何辅助实现多态,可以期待下篇文章:C++【多态】 ----

12410

C++继承

在封装过程中,我们发现有很多地方有问题,比如我们在封装Windows API 过程中,每个窗口都有各自消息处理,而我们封装时不同窗口要针对不同消息而编写不同消息处理函数,不可能所有窗口对于某些消息都进行相同处理...,所以在面向对象程序设计中,提供了一种新方式——继承与派生; 在c++中将继承一方称作派生类或者子类,将被继承一方叫做基类或者父类继承基本格式如下(CB 继承CA): class CA { public...,而对于析构调用顺序正好相反,先调用派生类在调用基类: 对于继承来说有三种:共有继承、私有继承以及保护继承继承方式不同,派生类对于基类各种不同属性之间成员访问权限不同,下面再给出一个表格用以说明这个问题...保护成员访问情况与私有相同,即类保护成员在类内可以访问在类外不能访问,它们二者区别在这个表中确实没有体现出来,主要区别可以在下一层继承中体现比如有三个类继承关系为CC->CB->CA,继承类型分别为...,我们知道基类非私有成员在保护继承下公有的变为保护,保护仍然为保护,而私有继承则是将所有都变为私有,他们之间如果都是保护继承方式,那么CA中其他成员在CB中都变为保护类型那么在CC中仍然能够访问到

57120

C++】继承

这篇文章开始,我们来学习一下C++中继承。 1. 继承概念及语法 相信大家对于继承这个词应该都不陌生,所以在这篇文章学习之前,大家可以先联想一下现实生活中继承是怎么样。...C++里面呢也有继承概念,那C++继承我们该如何去理解呢? 1.1 继承概念 其实不仅在C++这门语言里有继承概念,大多数面向对象语言都支持继承。...不需要,使用继承就很方便搞定了这些问题。...相信说到这里,大家对于C++中继承概念已经有了一定理解了,那继承语法是怎样呢?我们如何去定义一个继承类呢?...当然C++11有一个final关键字也可以解决这个问题。 那我们后面学到再说。

8710

C++】继承

但只要有多继承存在,就会出现菱形继承,而菱形继承就是C++继承一个大坑,Java知道C++因为有了多继承之后,出现菱形继承大坑,所以Java为了避免菱形继承大坑,规定Java只能有单继承不能有多继承...C++为了解决菱形继承带来问题采用了虚拟继承方式来进行解决,即在菱形继承腰部位置采用virtual继承来解决菱形继承大坑。 5....//C++引入虚拟继承来解决菱形继承数据冗余和二义性问题。...多继承可以认为是C++一个大坑,所以很多后来产生语言都没有多继承,只允许单继承存在,例如Java.继承和组合都是代码复用一种手段。 2....int _n; }; 九、经典笔试面试题 1.什么是菱形继承?菱形继承问题是什么?

63210

菱形继承问题及解决方法—虚继承与虚基类(C++)

菱形继承 菱形继承概念 两个派生类继承同一个基类,又有某个类同时继承着这两个派生类 菱形继承典型案例 这种继承带来问题主要有两方面: 羊和驼都继承了动物类成员,当羊驼想要使用时,会产生二义性...羊驼实际继承了两份来自动物数据,但实际只需要一份 想要解决有两个思路,一是给羊驼每一份数据加上作用域,但本质上羊驼还是继承了两份数据。...二是通过虚继承方式,使羊驼仅继承一份数据。...很明显羊驼从羊和驼两个父类中各自继承了一份m_Age,通过限定作用域方式无法彻底解决这个问题,这个时候就要使用虚继承继承与虚基类 具体实现为在羊类和驼类继承前加上virtual关键词,...可以看出羊类和驼类中数据只是一个虚基类指针,并未继承具体数据,这个虚基类指针指向各自虚基类表,而虚基类表中存在一个偏移量,通过这个偏移量再加上首地址可以找到基类中数据,所以实际上羊驼只继承了一份数据

96940

复杂C++继承

但是多继承给了别人犯错机会,这个犯错就是菱形继承 菱形继承 可以看到这个继承关系就像一个菱形一样,所以就叫菱形继承 菱形继承问题 因为Student和Teacher都是Person子类,也就是说这两个类中都有一份..._d = 2; d.B::_a = 3; d.C::_a =4; return 0; } 菱形虚拟继承 存在数据冗余和二义性问题根本原因就是同样一份Person成员数据在Assistant...中存在了两份,只要在继承时候加上virtual关键字就可以解决这个问题。...; 使用虚拟继承以后,_a只存在一份,这也就没有了二义性问题,但是继承于B类和C_b和_c上方多了一串地址,再次要通过内存查找这串地址,发现这串地址之后位置存放一个数字0x14,这个数字就是继承于...这样就解决了菱形继承成员冗余问题。 此时A被称为虚基类,继承B和C类要找到A中成员,就要通过虚基表中偏移量来计算。

20530

C++】继承 ⑪ ( 多继承 | 多继承语法 | 多继承案例 )

一、多继承 1、多继承基本语法 多继承 概念 : 一个 子类 ( 派生类 ) 可以 继承 多个 父类 ( 派生类 ) ; 一个类可以继承多个类属性和方法 ; 使用多继承 , 可以创建更复杂类 ,...该派生类可以组合多个基类功能 ; 只有 C++ 语言有多继承概念 , 别的语言没有该概念 ; Java 语言只能继承一个父类 , 可以实现多个接口 ; 多继承语法 : class 子类名称 : 访问控制关键字...y, int z): Parent1(x), Parent2(y) { this->c = z; } } 多个父类构造函数调用顺序 : 多个父类 构造函数 执行顺序 , 与 定义子类时...指定 父类顺序有关 ; 3、多继承中访问父类成员 子类 可能 继承多个 父类 , 父类 也有可能还有 父类 , 也就是说 子类 可能需要 访问 父类成员 , 爷爷类 成员 , 如果 访问 父类...多继承中 , 子类构造函数中 , 需要在 函数初始化列表 中 调用 父类 初始化函数 , 对 继承自 父类 成员变量 进行初始化操作 ; 代码示例 : #include "iostream" using

16330

C++】继承 ⑫ ( 继承二义性 | virtual 虚继承 )

一、继承二义性 1、场景说明 - 继承二义性 A 类 是 父类 , B 类 和 C继承 A 类 , 是 子类 , D 类 多继承 B 类 和 C 类 , 是 孙子类 ; 假如 A 类中有 成员变量...// 子类 B 继承了父类 A x 成员 class B : public A { public: int y; }; // 子类 C 继承了父类 A x 成员 class C : public..., 就会产生菱形继承结构 ; 这种情况下 , 可能会出现多个不同基类实例 , 导致重复定义和二义性 ; 为了应对上述 继承二义性 问题 , C++ 语言 使用 " 虚继承 " 解决 继承 二义性问题...; C++ 中 " 虚继承 " 是一种解决 多继承 带来 菱形问题(diamond problem)技术 ; 虚继承目的是 确保每个基类只被继承一次 , 从而避免 重复定义 和 二义性等问题... x 成员 class C : virtual public A { public: int z; }; // D 多继承 B 和 C // 分别从 B 和 C 各自继承一个来自 A 成员

14020
领券