正 文

C++对象布局及多态探索之菱形结构虚继承


www.7dspace.com  更新日期:2005-12-10 3:01:57  七度空间


  首先我们运行下面的代码,看看它们的内存布局。

PRINT_SIZE_DETAIL(C041)
PRINT_SIZE_DETAIL(C140)
PRINT_SIZE_DETAIL(C141)
PRINT_SIZE_DETAIL(C150)

  结果为:

The size of C041 is 5
The detail of C041 is f0 c2 45 00 01
The size of C140 is 14
The detail of C140 is 48 c3 45 00 02 00 00 00 00 44 c3 45 00 01
The size of C141 is 14
The detail of C141 is 58 c3 45 00 03 00 00 00 00 54 c3 45 00 01
The size of C150 is 20
The detail of C150 is 74 c3 45 00 02 68 c3 45 00 03 04 00 00 00 00 64 c3 45 00 01

  和前面的布局不同之处在于,共享部分和前面的非共享部分之间多了4字节的0值。只有共享部分有虚表指针,这是因为派生类都没有定义自己的虚函数,只是重写了顶层类的虚函数。我们分析一下C150的对象布局。

|C140,5 |C141,5 |C150,1 |zero,4 |C041,5 |
|ospt,4,15 |m,1 |ospt,4,10 |m,1 |m,1 |4 |vtpt,4 |m1 |

  (注:为了不折行,我用了缩写。ospt代表偏移值指针、m代表成员变量、vtpt代表虚表指针。第一个数字是该区域的大小,即字节数。只有偏移值指针有第二个数字,第二个数字就是偏移值指针指向的偏移值的大小。)

  再看函数的调用:

C150 obj;
PRINT_OBJ_ADR(obj)
obj.foo();

  输出的对象地址为:

obj's address is : 0012F624

  最后一行函数调用的代码对应的汇编代码为:

00423F74 lea ecx,[ebp+FFFFF757h]
00423F7A call 0041DCA3

  单步执行后,我们可以看到ecx中的值为:0x0012F633,这个地址也就是obj对象布局中的祖父类部分的起始地址。通过上面的布局分析我们知道 C150起始的偏移值指针指向的值为15,即对象起始到共享部分(祖父类部分)的偏移值。上面输出的obj起始地址为0x0012F624加上十进制的 15后,正好是我们看到的ecx中的值0x0012f633。

5页,页码:[1] [2] [3] [4] [5] 

上一篇:J2ME三种低级用户界面事件处理技术比较
下一篇:如何在活动目录中设置可登录的计算机
作者:潘凯  来源:VCHELP ( 责任编辑:7dspace )
收藏此页】【打印】【关闭
站 内 搜 索
 

热 点 导 读
特 别 推 荐