免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: cppfans6
打印 上一主题 下一主题

[C++] 基类指针变量都被赋值派生类的地址,但为什么不相等呢? [复制链接]

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
11 [报告]
发表于 2012-10-08 12:57 |只看该作者
i don't know any more, let me go.

论坛徽章:
6
技术图书徽章
日期:2013-11-13 11:11:27子鼠
日期:2014-02-20 17:54:13处女座
日期:2014-06-16 17:43:33午马
日期:2014-08-08 09:11:17未羊
日期:2014-08-10 11:57:072015年辞旧岁徽章
日期:2015-03-03 16:54:15
12 [报告]
发表于 2012-10-08 15:22 |只看该作者
本帖最后由 littledick 于 2012-10-08 15:26 编辑

指针指向的实例都是C类型的啊。{:3_198:}

用基类容器管理多类型子类实例集合时,通常会给子类实例在构造时就标识类型。在使用基类的指针作为容器操作参数,避免最后使用时出错。

论坛徽章:
0
13 [报告]
发表于 2012-10-08 20:56 |只看该作者
多重继承的关系?
我不清楚标准里面关于多重继承是怎么规定的,但看样子很像是因为多重继承的关系。
在多重继承的情况下,C在内存中的布局可能是:
_vfptr for A;
A::n;
_vfptr for B;
B::n;
C::n;
所以pa指向的是__vfptr for A, 而pb指向的是 __vfptr for B, 这两个之间还有一个int A::n, 所以差了8个字节。

我对c++的对象模型和多重继承都不清楚,所以只是猜测。

论坛徽章:
0
14 [报告]
发表于 2012-10-09 10:36 |只看该作者
本帖最后由 twinsen724 于 2012-10-09 14:35 编辑

问题在于这就是C++的MI模型,这个继承体系的模型可以看作(在内存中):

A subobject => &c & pa
B subobject => pb
C subobject

对于MI来说,A和B的sub object的起始地址不一样,这不同于SI(SI使用重叠模型)。但C因为继承于A和B,而A是第一个base class,B是第二个base class,在MI中,derived class subobject的起始位置和第一个base class subobject重合,从第二个base class subobject以及之后的,都有自己的独立起始地址。因此

&c == pa == &class A subobject
pb == &class B subobject

根据上面的描述,在MI中,用第二个以及之后的base class pointer保存一个derived class object的地址,compiler需要调整this指针,就在这一步:

B* pb = &c;

this调整到了B subobject的位置,因此造成了你所看到的现象。另外,因为你的hierarchy中有virtual function,这更佳复杂化了MI的内部操作。因为vptr的缘故:

pb->func();

也需要调整this指针,从而指向derived class subobject的地址,实际上就是C object的起始地址&c。

MI是传统C++复杂度的罪魁祸首,如果你再给你的hierarchy加上virtual base class,你会发现自己进入了迷宫。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP