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

C++:13---继承(单一继承、多重继承、多级继承、菱形继承继承

一、基类与派生类的概念 基类(父类):继承关系处于上层的类 派生类(子类):继承关系处于下层的类 class A; class B; class C:public A //C为A的子类,A为C...宏观上叫做多级继承 class A{}; class B :public A {}; class C :public B { }; 七、菱形继承 概念:A作为基类,BC都继承与A。...最后一个类D又继承于BC,这样形式的继承称为菱形继承 菱形继承的缺点: 数据冗余:D中会保存两份A的内容 访问不明确(二义性):因为D不知道是以B为中介去访问A还是以C为中介去访问A,因此访问某些成员的时候会发生二义性...继承也可以解决这个问题 ?...继承的作用:为了保证公共继承对象创建时只保存一分实例 继承解决了菱形继承的两个问题: 数据冗余:顶级基类整个体系只保存了一份实例 访问不明确(二义性):可以不通过作用域访问符::来调用(原理就是因为顶级基类整个体系只保存了一份实例

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

C++:53---菱形继承继承

一、菱形继承 介绍继承之前介绍一下菱形继承 概念:A作为基类,BC都继承与A。...继承的作用:为了保证公共继承对象创建时只保存一分实例 继承解决了菱形继承的两个问题: 数据冗余:顶级基类整个体系只保存了一份实例 访问不明确(二义性):可以不通过作用域访问符::来调用(原理就是因为顶级基类整个体系只保存了一份实例...,则会产生二义性 例如,D1D2继承与B,D继承于D1D2,并且B有一个x成员: 如果D1D2都没有x的定义:此时对x的访问不会产生二义性,因为只含有x的一个实例 如果D1有x的定义而D2没有...解决二义性最好的办法就是派生类为成员自定义新的实例 五、继承的构造函数 继承的构造函数与普通继承的构造函数不一样: 普通继承:派生类可以不为间接基类(基类的基类)进行构造函数的调用 继承:不论派生类属于哪一层...,与它们继承体系的次序位置无关 例如,在上面的演示案例,构造顺序为:A-->B-->C-->D 下面再演示一个有多个基类的例子,其构造函数执行熟悉怒为: ZooAnimal ToyAnimal

73430

C++继承

如果一个类从多个类继承而来,而这些类有公共基类。那么多该基类定义的成员访问时会出现二义性。C++设计继承来解决这个问题。继承的本质就是子类引用父类的内存空间,而不创建自己的内存空间。...这样既解决了多重继承可能引发的二义性问题,也使得内存得以释放。...继承过程的基类被叫做:基类 那么实际上,继承的本质就是使用一个指向基类的指针,这样就无论你怎么继承,就只有一份基类内存空间。 C++使用关键字virtual来进行继承。...{ }; int main() { Last L; L.a; return 0; } 通过继承,这样MyClass类的内存空间只有一份。...这种情况下,继承也无法帮到我们。我们只能使用 c.A::a; c.B::a; 来明确对类成员的调用,从而避免二义性的产生。

83920

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

public Base{}; 可以看到, Byte Expert 的继承后面使用了 virtual 关键字进行了修饰。...这时,Base 便成了 Byte Expert 的基类,达成了继承的方式,Base 类最终的 Blu 类只存在一个,所以不存在命名空间冲突及资源浪费。...基类并不是“绝对的”,而是“相对的”:基类它自身声明、定义的时候无需任何修饰,只是子类继承时进行 virtual 修饰。...所以 Blu 类仍然存在菱形继承的问题,所有需要将所有继承同一基类的上级父类继承方式声明为 virtual。...同时,继承机制当中,基类是由最终的派生类进行初始化的,本身达成了一种 “间接继承” 的关系。 也就意味着最终的派生类构造函数初始化,要在初始化表调用基类的构造函数进行初始化。

91530

深入解析C++函数继承实现多态性与继承关系的高级特性

这里写目录标题 函数 函数实现动态绑定 继承 抽象类 函数 函数是C++中用于实现多态性的一种特殊函数。它通过使用关键字"virtual"进行声明,基类定义,可在派生类中进行重写。...这使得继承关系,通过基类指针或引用调用函数时,可以根据实际对象的类型来动态地确定要执行的函数版本,实现多态性的特性。...函数定义 C++ ,可以通过函数声明前面加上关键字 virtual 来定义函数。...C++,当基类的指针或引用指向派生类的对象时,通过调用函数,可以实现对应于派生类的特定实现。这种根据对象的实际类型来确定调用哪个函数的机制就是动态绑定。...继承(Virtual Inheritance)是C++的一种继承方式,用于解决多继承的菱形继承问题。

1.1K10

从零开始学C++继承(三):多重继承继承基类

,更好的软件重用 可能会有大量的二义性,多个基类可能包含同名变量或函数 多重继承解决访问歧义的方法: 基类名::数据成员名(或成员函数(参数表)) 明确指明要访问定义于哪个基类的成员...只能通过 sofaBed.Bed::weight_ = 10; 访问,但实际上一个sofaBed理应只有一个weight_,下面通过基类继承可以解决这个问题。...二、继承基类 当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类的成员时,将产生二义性,可以采用基类来解决。...2、整个继承结构,直接或间接继承基类的所有派生类,都必须在构造函数的成员初始化表给出对基类的构造函数的调用。如果未列出,则表示调用该基类的默认构造函数。...参考: C++ primer 第四版 Effective C++ 3rd C++编程规范

1K00

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

40; // 控制台暂停 , 按任意键继续向后执行 system("pause"); return 0; } 执行结果 : 二、virtual 继承 1、继承引入 继承 , 如果一个类继承了多个含有相同基类的派生类..., 就会产生菱形继承结构 ; 这种情况下 , 可能会出现多个不同的基类实例 , 导致重复定义二义性 ; 为了应对上述 继承的二义性 问题 , C++ 语言 使用 " 继承 " 解决 继承的 二义性问题...; C++ 的 " 继承 " 是一种解决 多继承 带来的 菱形问题(diamond problem)的技术 ; 继承的目的是 确保每个基类只被继承一次 , 从而避免 重复定义 二义性等问题...; 继承 通过 派生类 中使用关键字 virtual 来指示基类应该被继承 , 继承确保了每个基类只被继承一次 , 从而避免了重复定义二义性 ; C++ ,使用继承的语法是基类列表中使用...virtual 关键字 ; 2、继承语法 继承语法 : 继承的 访问限定符 之前 , 添加 virtual 关键字 , 将该继承行为定义为 " 继承 " ; class 子类类名 : virtual

17320

C++|对象模型|多继承机制实现

本文参考深度探索C++对象模型 ---- 我们常常使用基类指针指向派生类对象,那么,为什么基类指针能够如此轻松的调用派生类的方法呢?继承的情况下,this指针必须经过调整,才能正确地找到表。...下文为你介绍多继承模型下的指针偏移机制 ---- 指针偏移存在机制: 设一个多继承的类内存布局如下,单词代表对象首地址。...例如:对于Base1Base2而言,如果Base2定义clone,Derived重写了clone,那么需要向后调整Base1长度以正确指向Derived object ---- 使用派生类指针指向派生类...调用时:派生->基 指向派生类的指针,调用第二个基类继承来的函数。...---- 指针偏移实现机制: 1.赋值:转型 temp为已知Derived指针。 Base2 * pbase2 =temp ?

51220

c++头脑风暴-多态、继承、多重继承内存布局

,一样的只是基类基础上增加了派生类的成员变量而已,接下来我们派生类实现基类同样的函数看看会发生什么。...总结一下:c++继承时的多态一般指的运行时多态,使用基类指针或者引用指向一个派生类对象,非虚继承的情况下,派生类直接继承基类的表指针,然后使用派生类的函数去覆盖基类的函数,这样派生类对象通过表指针访问到的函数就是派生类的函数了...三、继承 如果仔细看的话,可以发现我先前多次强调了非虚继承,这是因为没有函数的时候是不是继承影响不大,但存在函数的时候继承非虚继承是不一样的,如下: #include ...这说明继承不只是实现了派生类自己的表指针,还重新生成了属于它自己的函数表,但这样一来,等于继承就比非虚继承多了很多开销,所以大多数情况还是不要使用继承吧。...,如果派生类有同样的函数,那就覆盖基类同名函数,如果是派生类独有的函数,那就追加在基类函数表后面; 一个派生类继承于一个有函数且没有成员变量的基类,则派生类也不会生成它自己的表指针函数表

64320

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

菱形继承 菱形继承的概念 两个派生类继承同一个基类,又有某个类同时继承着这两个派生类 菱形继承典型案例 这种继承带来的问题主要有两方面: 羊驼都继承了动物的类成员,当羊驼想要使用时,会产生二义性...二是通过继承的方式,使羊驼仅继承一份数据。...自带的命令提示工具,到cpp文件存放目录后执行cl /d1 reportSingleClassLayoutSheepTuo test.cpp,其中test.cpp就是文件名,执行结果如下: 很明显羊驼从羊驼两个父类各自继承了一份...m_Age,通过限定作用域的方式无法彻底解决这个问题,这个时候就要使用继承 继承基类 具体实现羊类驼类的继承前加上virtual关键词,Animal类称为基类 代码如下: #include...可以看出羊类驼类的数据只是一个基类指针,并未继承具体的数据,这个基类指针指向各自的基类表,而基类表存在一个偏移量,通过这个偏移量再加上首地址可以找到基类的数据,所以实际上羊驼只继承了一份数据

1.1K40

C++:14---继承函数,多态

::data=3;//访问C的 D.B::A::data=4;//访问B继承的A D.C::A::data=5;//访问C继承的A D.A::data=4;//错误,产生二义性,不知道是B、C哪一个...此种菱形继承多存储了两倍的A的内存段,下面将介绍基类 ? 二、基类(virtual) 1.概念:也称继承、菱形继承。...B,于是去构造B,构造B的时候,发现继承基类A,于是构造基类A,接着构造B。...//12sizeof(D); //24 4.内存地址图解 基类的内存地址派生类内存地址的最后 基类派生时,只保存一份内存在派生类内存 ?...地址解析: BC中都保存了A的值,但是D继承BC的时候,只保存了一份A,且放在最后 D继承的BC内存段中分别有一个函数指针放在最前方 二、函数表 1.概念:是一块连续的内存,所有函数的首地址都存放在函数表

69810

继承三角钻石问题(继承

上一篇文章我们简单介绍了一下多继承的语法,但是我们遇到了一个问题,那就是如果多个父类具有相同名称的成员变量或成员方法,子类调用的时候就会出现二义性问题,子类不知道选择哪一个父类的变量或方法,我们称之为三角问题...设计类的过程,如果多个父类出现了同名的公有成员变量或方法,并且方法所执行的认为是一模一样的情况下,这证明我们设计的类是有问题的,应该保证实现同一功能的方法只有一个。...那在上面的案例我们需要抽象出一个基类,这个基类将SofaBed两个类的公有同名变量或成员存放到基类,然后让 Sofa Bed 使用继承的方式,继承这个基类,这时,子类再多继承 Sofa ...其中 继承 起到了重要的作用,他让基类派生的两个类只保留了一份共有公共成员,这种情况,我们称之为钻石问题。...#include using namespace std; class M { public: int data; }; // 继承 M 类 class Bed : virtual public M

14830

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

一、继承原理 1、继承解决继承二义性问题 继承的二义性 : 如果 一个 子类 ( 派生类 ) 继承多个 父类 ( 基类 ) , 这些父类 都继承了 相同的父类 , 那么 子类 访问 父类的父类 的成员..., 就会产生 二义性 ; 报错 : error C2385: 对“x”的访问不明确 ; 使用 " 继承 " 可以解决上述问题 , 子类 继承父类时 , 访问限定符 之前使用 virtual 关键字..., 即可将 普通继承 改为 继承 ; 下面的代码 A 是父类 ; B 类 C 类 继承 A 类 , 这样当 某个类 同时 多继承 B 类 C 类时 , 访问 A 类的成员时 , 不会出现...二义性 ; 由于 B C 继承 A , D 类访问 A 的成员 , 不会产生二义性 ; class A { public: int x; }; // 子类 B 继承了父类 A 的 x 成员..., 为 A 类 , B 类 , C 类 , D 类 , 都定义一个默认的 无参构造函数 , 每个构造函数 打印相关信息 ; B 类 C 类都 继承 A 类 , 最终构建 D 类使 , 发现 A

26520

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

继承语法 C++允许一个类继承多个类 语法: class 子类 :继承方式 父类1 , 继承方式 父类2......多继承可能会引发父类中有同名成员出现,需要加作用域区分 C++实际开发不建议用多继承 示例: class Base1 { public: Base1() { m_A = 100; } public...; cout << s.Base2::m_A << endl; } int main() { test01(); system("pause"); return 0; } 总结: 多继承如果父类中出现了同名情况...示例: class Animal { public: int m_Age; }; //继承前加virtual关键字后,变为继承 //此时公共的父类Animal称为基类 class Sheep :...使用了继承后对比未使用继承解决菱形继承 总结: 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义 利用继承可以解决菱形继承问题

70310

C++虚拟继承基类

1.多重继承带来的问题 C++虚拟继承一般发生在多重继承的情况下。C++允许一个类有多个父类,这样就形成多重继承。...所以,在上面的程序show()显示的是Employee的成员(IDPersonName)。...实际上,EGStudent类对象还有来自Student类的成员(IDPersonName)。...(2)被虚拟继承的基类,叫做基类。基类实际指的是继承的方式,而非一个基类,是动词,而非名词。 (3)为了实现虚拟继承,派生类对象的大小会增加4。...因为虚拟继承只是表名某个基类的对象派生类对象只被构造一次,而在本例类StudentEmployee对象EGStudent对象本来就不会被构造多次,所以不将它们申明基类也是完全可以的。

87220

C++接口继承实现继承的区别选择

1.接口继承实现继承的区别 《Effective C++》条款三十四:区分接口继承实现继承中介绍的比较啰嗦,概括地说需要理解三点: (1)纯函数只提供接口继承,但可以被实现; (2)函数既提供接口继承...函数必须有实现,否则会报链接错误。函数可以基类多个派生类中提供不同的版本,利用多态性质,程序运行时动态决定执行哪一个版本的函数(机制是编译器生成的表)。...事实上,也是极不推荐派生类隐藏基类的普通函数,如果真的要这样做,请一定要考虑是否该把基类的这个函数声明为函数或者纯函数。 下面看一个示例程序。...基类CShape,不能够为每一种不同的图形提供一个默认的draw实现,所以设置为纯函数,留给派生类来实现,也就说派生类只是继承了一个借口而已。...---- 参考文献 [1]读书笔记Effective_C++条款三十四:区分接口继承实现继承 [2]李健.编写高质量代码:改善C++程序的150个建议[M].第一版.北京:机械工业出版社,2012.1

1.2K20

c++C++继承&&菱形继承详解

继承体系基类派生类都有独立的作用域 子类父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。...(子类成员函数,可以使用 基类::基类成员 显示访问) 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏 注意在实际继承体系里面最好不要定义同名的成员 Student的_numPerson...funA的fun不是构成重载,因为不是同一作用域 B的funA的fun构成隐藏,成员函数满足函数名相同就构成隐藏 // B的funA的fun不是构成重载,因为不是同一作用域 //...这里是通过了BC的两个指针,指向的一张表。这两个指针叫基表指针,这两个表叫基表。基表存的偏移量。...如何解决数据冗余二义性的 菱形继承问题继承是如何解决二义性与数据冗余的_数据的二义性-CSDN博客 C++继承的问题 : 菱形继承 (虚拟继承)_c++菱形继承问题-CSDN博客 3.

9910

c++】多态&&函数&&抽象类&&继承函数表详解

多态的定义及实现 2.1 多态的构成条件 多态是不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。...void Test() { Car* pBenz = new Benz; pBenz->Drive(); Car* pBMW = new BMW; pBMW->Drive(); } 3.2 接口继承实现继承...普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。...单继承继承关系函数表 5.1 单继承函数表 class Base { public: virtual void func1() { cout << "Base::func1" <<...所以菱形继承、菱形虚拟继承我们的表我们就不看了,一般我们也不需要研究清楚,因为实际很少用 C++ 函数表解析 | 酷 壳 - CoolShell C++ 对象的内存布局 | 酷 壳 - CoolShell

32810
领券