继承体系下派生类的对象模型

举报
竹叶青 发表于 2019/10/15 12:55:41 2019/10/15
【摘要】 博客链接:https://blog.csdn.net/qq_39412582/article/details/81273137 看到标题我们首先应该想到的是什么是对象模型? 那好,什么是对象模型呢?**对象模型就是对象中非静态成员变量在内存中的布局形式。**但是,我们要看这个布局只能在内存中查看,在监视窗口可能不会看到我们想要看到的结果(C++中经常会遇到这种事情,你看到的并不一定就是真的)...

top0.97ac691.png

博客链接:https://blog.csdn.net/qq_39412582/article/details/81273137 看到标题我们首先应该想到的是什么是对象模型? 那好,什么是对象模型呢?**对象模型就是对象中非静态成员变量在内存中的布局形式。**但是,我们要看这个布局只能在内存中查看,在监视窗口可能不会看到我们想要看到的结果(C++中经常会遇到这种事情,你看到的并不一定就是真的)。

那么什么又是继承呢? 继承:就是在一个已存在的类的基础上建立一个新的类,而这个新的类又从已有的类获得其原有的特性,这个现象叫做类的继承。 **派生:**从父类继承出来的子类叫做类的派生。 根据继承方式可分为: 单继承 多继承 菱形继承 虚拟继承 菱形虚拟继承 五种

单继承

一个派生类只能从一个基类派生叫做单继承。 类似于树形结构。 继承方式:

image.png

多继承

继承方式:

image.png

前两种继承方式很简单,这里就不多介绍了。

菱形继承

看个例子:

image.png

继承方式:为什么会编译错误?那是因为存在二义性。 要怎么解决呢? 本文提供两种解决方案: ⑴d.C1::_b=10 //来自那一个类里面的_b要写清楚,这样就不会报错 ⑵ 就要用到菱形虚拟继承

看一段代码:

image.png

思考一下这里的**sizeof(D)**应该是多少?可以看到结果就是我们所想的那样。 但是当我们在20 行下断点进行调试的时候发现它并没有停下来,我们给的情景是

想要让编译器为我们合成构造函数,先来看看虚拟继承。

虚拟继承

image.png

image.png

这里的**sizeof(D)**又是多少呢?

可以看到这次编译器在18行给我们停了下来,但是却多了4个字节,说明它为我们创建了构造函数。 然后我们在内存中看看它到底什什么情况:

怎么来理解呢?我以画图的形式给大家做出详细的解释:


70

如果这个例子不够满意的话,你还可以去看看反汇编,看看代码在底层是怎么实现的。


70

我们可以把这个eax+4 这个寄存器强转成 int* 类型在解引用就可以发现它也是 8

菱形虚拟继承

在上面我们说普通的菱形继承存在二义性问题,除了加上作用域限定符之外还可以用菱形虚拟继承来解决。下面就跟着我看看本篇文章最后的一个问题把:

那什么是菱形虚拟继承?聪明的人一下就会想到,就是在菱形继承里加上virtual这个虚拟关键字不就OK了,没错就是这样。

image.png

那这里的sizeof应该是多少呢?24?还是28?


70

怎么理解呢:我通过画图的方式给大家解答


70

再说两个面试题: ⑴设计一个类,该类不能被继承? 答:可以用private 访问限定符来做到不能被继承问题,还有一种方法就是C++11里面给出的final关键字,添加在类的后面。 ⑵为什么菱形虚拟继承能够解决菱形继承中二义性的问题? 上面的文章已经给出了答案,相信你已经OK了。

本文转载自异步社区

原文链接:

https://www.epubit.com/articleDetails?id=N06a63c65-72c5-45f7-a433-2a8147bb6fb2


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。