首页
社区
课程
招聘
[原创]多重继承?抽象类?C++的内存布局并不复杂
发表于: 2019-10-16 21:37 3829

[原创]多重继承?抽象类?C++的内存布局并不复杂

2019-10-16 21:37
3829

在上面的代码,我们看出构造函数的调用顺序是根据,从左到右的继承顺序来依次调用父类函数的

在调用cFa的构造函数时,直接传递了this指针,也就是cCh的地址,而在调用cMo的时候,传递的是this指针加4个字节的地址,也就是跳过了cFa所占的空间。


那么也就是说,父类对象在子类的内存布局的顺序和构造函数的调用顺序是一样的,那么现在cCh对象的内存结构如下图:

过滤掉了一些无用的代码,构造函数和非多重继承无任何区别,只是将传进来的对象的虚表换成自己的虚表。


有营养的部分来了:

两个构造函数结束后,出现了两个虚表赋值,为什么是两个虚表?

因为有两个父类,当调用父类函数的时候,需要通过偏移取得父类对象,传递指针,并调用函数。


这两个虚表在本例中意义不大,因为子类没有覆盖父类的虚函数,如果有覆盖的情况出现,这两个虚表中会保存子类覆盖的虚函数,和父类未覆盖的虚函数。那么调用就很简单了,虚表偏移。


析构函数就不上代码了,和构造函数的顺序恰巧相反。

如果在main函数中添加一行如下代码会发生什么?

上代码

看起来似乎和普通的继承没什么不同?

我们来看看CAbstractBase中的虚函数表(0A18B34h)指向的Show函数吧。




CAbstractBase的Show函数,没有实现代码,所以没有首地址,编译器防止误调用纯虚函数,将虚表中保存的纯虚函数的首地址项替换成了__purecall 函数,这个函数的作用就是结束程序,并返回错误码0x19。


其余与单类继承并无差别。

单类继承:

多重继承:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-10-17 18:01 被Hasic编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 83
活跃值: (1087)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
__purecall  f返回错误 啥意思 没看懂
2019-10-17 14:42
0
雪    币: 612
活跃值: (479)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
killpy __purecall f返回错误 啥意思 没看懂
CAbstractBase的Show函数,没有实现代码,所以没有首地址,编译器防止误调用纯虚函数,将虚表中保存的纯虚函数的首地址项替换成了__purecall 函数,这个函数的作用就是结束程序,并返回错误码0x19。
2019-10-17 18:01
0
游客
登录 | 注册 方可回帖
返回
//