继承体系下派生类的对象模型
博客链接:https://blog.csdn.net/qq_39412582/article/details/81273137 看到标题我们首先应该想到的是什么是对象模型? 那好,什么是对象模型呢?**对象模型就是对象中非静态成员变量在内存中的布局形式。**但是,我们要看这个布局只能在内存中查看,在监视窗口可能不会看到我们想要看到的结果(C++中经常会遇到这种事情,你看到的并不一定就是真的)。
那么什么又是继承呢? 继承:就是在一个已存在的类的基础上建立一个新的类,而这个新的类又从已有的类获得其原有的特性,这个现象叫做类的继承。 **派生:**从父类继承出来的子类叫做类的派生。 根据继承方式可分为: 单继承 多继承 菱形继承 虚拟继承 菱形虚拟继承 五种
单继承
一个派生类只能从一个基类派生叫做单继承。 类似于树形结构。 继承方式:
多继承
继承方式:
前两种继承方式很简单,这里就不多介绍了。
菱形继承
看个例子:
继承方式:为什么会编译错误?那是因为存在二义性。 要怎么解决呢? 本文提供两种解决方案: ⑴d.C1::_b=10 //来自那一个类里面的_b要写清楚,这样就不会报错 ⑵ 就要用到菱形虚拟继承
看一段代码:
思考一下这里的**sizeof(D)**应该是多少?可以看到结果就是我们所想的那样。 但是当我们在20 行下断点进行调试的时候发现它并没有停下来,我们给的情景是
:
想要让编译器为我们合成构造函数,先来看看虚拟继承。
虚拟继承
这里的**sizeof(D)**又是多少呢?
可以看到这次编译器在18行给我们停了下来,但是却多了4个字节,说明它为我们创建了构造函数。 然后我们在内存中看看它到底什什么情况:
怎么来理解呢?我以画图的形式给大家做出详细的解释:
如果这个例子不够满意的话,你还可以去看看反汇编,看看代码在底层是怎么实现的。
我们可以把这个eax+4 这个寄存器强转成 int* 类型在解引用就可以发现它也是 8
菱形虚拟继承
在上面我们说普通的菱形继承存在二义性问题,除了加上作用域限定符之外还可以用菱形虚拟继承来解决。下面就跟着我看看本篇文章最后的一个问题把:
那什么是菱形虚拟继承?聪明的人一下就会想到,就是在菱形继承里加上virtual这个虚拟关键字不就OK了,没错就是这样。
那这里的sizeof应该是多少呢?24?还是28?
怎么理解呢:我通过画图的方式给大家解答
再说两个面试题: ⑴设计一个类,该类不能被继承? 答:可以用private 访问限定符来做到不能被继承问题,还有一种方法就是C++11里面给出的final关键字,添加在类的后面。 ⑵为什么菱形虚拟继承能够解决菱形继承中二义性的问题? 上面的文章已经给出了答案,相信你已经OK了。
本文转载自异步社区
原文链接:
https://www.epubit.com/articleDetails?id=N06a63c65-72c5-45f7-a433-2a8147bb6fb2 |
- 点赞
- 收藏
- 关注作者
评论(0)