分享
 
 
 

我看vc6中虚继承的实现

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

这两天试了一下,来说两句

因手头上只有vc6编译器,故只看了vc6的方式

我的测试程序如下

#include "stdafx.h"

class mostbase1

{

public:

mostbase1():i(1){};

int i;

};

class mostbase2

{

public:

mostbase2():j(2){};

int j;

};

class base1:public virtual mostbase1,public virtual mostbase2

{

};

class base2:public virtual mostbase1,public virtual mostbase2

{

};

class derived:public base1,public base2

{

};

void f(derived* pderived)

{

mostbase1* pbase1 = pderived;

mostbase2* pbase2 = pderived;

int k = pderived->i;

k = pderived->j;

k = pbase1->i;

k = pbase2->j;

}

int main(int argc, char* argv[])

{

derived d;

f(&d);

printf("Hello World!\n");

return 0;

}

经过我的测试及查看汇编代码,得知vc的虚基类转换确如Inside the c++ objects model中所说是用一个virtual base class table来实现的

base1和base2中各有一个__vbct__ptr(大小是4个字节)用来指向一个virtual base class table,该表格存储着base类中虚基类在base类中的偏移,其后就是数据,当derived继承自base1和base2,首先是存放base1和base2的__vbct_ptr,再就是数据,将base1和base2相同基类的数据放到一起

base1类的内存布局如下(base2与base1相同):

pvoid* __vbct_base1 ----先是虚基类表的地址,此时__vbct_base1数据如下

----00 00 00 00 04 00 00 00 08 00 00 00

----mostbase1在base1中的偏移为[__vbct_base1+4]的值

int i; ----mostbase1类中的i

int j; ----mostbase2类中的j

derived类的内存布局如下:

pvoid* __vbct_base1; ----base1类的虚基类表的地址,其中的值有变化,数据如下

----00 00 00 00 08 00 00 00 0C 00 00 00

pvoid* __vbct_base2; ----base2类的虚基类表的地址,数据如下

----00 00 00 00 04 00 00 00 08 00 00 00

int i;

int j;

下面是f(derived* pderived)函数的汇编代码,对其它进行分析

29: void f(derived* pderived)

30: {

0040C230 push ebp

0040C231 mov ebp,esp

0040C233 sub esp,60h

0040C236 push ebx

0040C237 push esi

0040C238 push edi

0040C239 lea edi,[ebp-60h]

0040C23C mov ecx,18h

0040C241 mov eax,0CCCCCCCCh

0040C246 rep stos dword ptr [edi]

31: mostbase1* pbase1 = pderived;

0040C248 cmp dword ptr [ebp+8],0 [1]

0040C24C jne f+27h (0040c257)

0040C24E mov dword ptr [ebp-18h],0 [2]

0040C255 jmp f+35h (0040c265)

0040C257 mov eax,dword ptr [ebp+8]

0040C25A mov ecx,dword ptr [eax] [3]

0040C25C mov edx,dword ptr [ebp+8]

0040C25F add edx,dword ptr [ecx+4] [4]

0040C262 mov dword ptr [ebp-18h],edx

0040C265 mov eax,dword ptr [ebp-18h]

0040C268 mov dword ptr [ebp-4],eax [5]

32: mostbase2* pbase2 = pderived;

0040C26B cmp dword ptr [ebp+8],0

0040C26F jne f+4Ah (0040c27a)

0040C271 mov dword ptr [ebp-1Ch],0 [6]

0040C278 jmp f+58h (0040c288)

0040C27A mov ecx,dword ptr [ebp+8]

0040C27D mov edx,dword ptr [ecx] [7]

0040C27F mov eax,dword ptr [ebp+8]

0040C282 add eax,dword ptr [edx+8] [8]

0040C285 mov dword ptr [ebp-1Ch],eax

0040C288 mov ecx,dword ptr [ebp-1Ch]

0040C28B mov dword ptr [ebp-8],ecx

33: base1* p1 = pderived;

0040C28E mov edx,dword ptr [ebp+8]

0040C291 mov dword ptr [ebp-0Ch],edx [9]

34: p1->i = 1;

0040C294 mov eax,dword ptr [ebp-0Ch]

0040C297 mov ecx,dword ptr [eax]

0040C299 mov edx,dword ptr [ecx+4] [10]

0040C29C mov eax,dword ptr [ebp-0Ch]

0040C29F mov dword ptr [eax+edx],1

35: base2* p2 = pderived;

0040C2A6 cmp dword ptr [ebp+8],0

0040C2AA je f+87h (0040c2b7)

0040C2AC mov ecx,dword ptr [ebp+8]

0040C2AF add ecx,4 [11]

0040C2B2 mov dword ptr [ebp-20h],ecx

0040C2B5 jmp f+8Eh (0040c2be)

0040C2B7 mov dword ptr [ebp-20h],0

0040C2BE mov edx,dword ptr [ebp-20h]

0040C2C1 mov dword ptr [ebp-10h],edx [12]

36: p2->j = 1;

0040C2C4 mov eax,dword ptr [ebp-10h]

0040C2C7 mov ecx,dword ptr [eax]

0040C2C9 mov edx,dword ptr [ecx+8] [13]

0040C2CC mov eax,dword ptr [ebp-10h]

0040C2CF mov dword ptr [eax+edx],1

37: int k = pderived->i;

0040C2D6 mov ecx,dword ptr [ebp+8]

0040C2D9 mov edx,dword ptr [ecx]

0040C2DB mov eax,dword ptr [edx+4] [14]

0040C2DE mov ecx,dword ptr [ebp+8]

0040C2E1 mov edx,dword ptr [ecx+eax] [15]

0040C2E4 mov dword ptr [ebp-14h],edx

38: k = pderived->j;

0040C2E7 mov eax,dword ptr [ebp+8]

0040C2EA mov ecx,dword ptr [eax]

0040C2EC mov edx,dword ptr [ecx+8] [16]

0040C2EF mov eax,dword ptr [ebp+8]

0040C2F2 mov ecx,dword ptr [eax+edx]

0040C2F5 mov dword ptr [ebp-14h],ecx

39:

40: }

0040C2F8 pop edi

0040C2F9 pop esi

0040C2FA pop ebx

0040C2FB mov esp,ebp

0040C2FD pop ebp

0040C2FE ret

[1]dword ptr [ebp+8h]就是pderived,先看看是不是为NULL.

[2]dword ptr [ebp-18h]是一个中间变量,当pderived为NULL时,将其也赋为NULL

[3]取出__vbct_base1,其位置在derived类的开始处

[4]取出mostbast1类在derived中的偏移,此值在_vbct_base1+4的位置,占用4个字节,其值为8, 因为derived前有两个__vbct_prt,都为4字节,故mostbast1在derived的偏移为8.

[5]将pbase1赋值,dword ptr [ebp-4]存放pbase1;

[6]同(2),只是中间变量的地址不同

[7]同(3),取出__vbct_base1

[8]同(4), 取出mostbast2类在derived中的偏移,此时为12

[9]取出derived类中的base1的地址,也就是derived中__vbct_base1的地址,可能你有疑问,看下面

[10]用p1存取数据时,还是通过__vbct_base1来做的,通过__vbct_base1得到mostbase1在derived中 的偏移,最后得到的地址是pderived+8

[11]现在取出__vbct_base2的地址,看到了add ecx,4么

[12]将p2赋值

[13]通过__vbct_base2来取得mostbase2的地址,再来存取j

[14]通过__vbct_base1来取得mostbase1的地址

[15]偏移在eax中,取出i来

[16]通过__vbct_base1来取得mostbase2的地址

以下是我构想的c伪码,可能不太正确,因为汇编代码已经优化过

void f(derived* pderived)

{

----mostbase1* pbase1 = pderived;

mostbase1 *pbase1,*temp1;

if (pderived == 0)

{

temp1 = 0;

}

else

{

temp1 = (mostbase1*)(pderived+(pderived->__vbct_base1[1]));

}

pbase1 = temp1;

----mostbase2* pbase2 = pderived;

mostbase2 *pbase2,*temp2;

if (pderived == 0)

{

temp2 = 0;

}

else

{

temp2 = (mostbase2*)(pderived+(pderived->__vbct_base1[2]));

}

pbase2 = temp2;

----base1* p1 = pderived;

base1* p1 = &pderived->__vbct_base1;

----p1->i = 1;

(mostbase1*)(p1+p1->__vbct_base1[1])->i = 1;

----base2* p2 = pderived;

base2* p2 = &pderived->__vbct_base2;

----p2->j = 1;

(mostbase2*)(p2+p2->__vbct_base2[2])->j = 1;

----int k = pderived->i;

int k = (mostbase1*)(pderived+pderived->__vbct_base1[1])->i;

----k = pderived->j;

k = (mostbase2*)(pderived+pderived->__vbct_base1[2])->j;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有