设为首页 加入收藏

TOP

12.4 菱形继承(3)
2013-10-07 14:30:47 来源: 作者: 【 】 浏览:62
Tags:12.4 菱形 继承

12.4 菱形继承(3)

从代码清单12-14中的指针转换过程可以看出,vt_offset指向的内存地址中保存的数据为偏移数据,如图12-15所示,图中每个vt_offset对应的数据有两项:第一项为-4,即vt_offset所属类对应的虚表指针相对于vt_offset的偏移值;第二项保存的是父类虚表指针相对于vt_offset的偏移值。

 
(点击查看大图)图12-15 vt_offset指向的数据
根据对代码清单12-13的分析可知,3个虚表指针分别为0x00425034、0x00425028、0x0042501C,它们所指向的数据如图12-16所示。
 
(点击查看大图)图12-16 各个虚表信息

如图12-16所示,这三个虚表指针所指向的虚表包含了子类CSofaBed含有的虚函数。有了这些记录就可以随心所欲地将虚表指针转换成任意的父类指针。在利用父类指针访问虚函数时,只能调用子类与父类共有的虚函数,子类继承自其他父类的虚函数是无法调用的,虚表中也没有相关的记录。当子类的父类也存在多个父类时,会在图12-15所显示的表格中依次记录它们的偏移。

学习了菱形结构中子类的内存布局后,接下来分析其子类的构造函数,看看这些数据是如何产生的,如代码清单12-15所示。

代码清单12-15 菱形结构的子类构造

  1.     CSofaBed SofaBed;  
  2. 0040F730        push 1                      ; 压入参数1  
  3. 0040F732    lea     ecx,[ebp-34h]               ; 传递this指针  
  4. 0040F735    call    @ILT+10(CSofaBed::CSofaBed) (0040100f); 调用构造函数  
  5.     ; 构造函数实现  
  6.     CSofaBed(){  
  7.     ; 部分代码分析略  
  8. 004011FE    pop     ecx                 ; 还原this指针  
  9. 004011FF    mov     dword ptr [ebp-10h],ecx  
  10. 00401202    mov     dword ptr [ebp-14h],0           ; 传入构造标记  
  11.     ; 比较参数是否为0,为0则执行JE跳转,防止重复构造  
  12. 00401209    cmp     dword ptr [ebp+8],0  
  13. 0040120D    je      CSofaBed::CSofaBed+6Eh (0040123e)  
  14. 0040120F    mov     eax,dword ptr [ebp-10h]  
  15.     ; 设置父类CSofa中的vt_offset域  
  16. 00401212    mov     dword ptr [eax+4],offset CSofaBed::'vbtable' (00425050)  
  17. 00401219    mov     ecx,dword ptr [ebp-10h]  
  18.     ; 设置父类CBed中的vt_offset域  
  19. 0040121C    mov     dword ptr [ecx+10h],offset CSofaBed::'vbtable' (00425044)  
  20. 00401223    mov     ecx,dword ptr [ebp-10h]  
  21. 00401226    add     ecx,20h             ; 调整this指针  
  22.     ; 调用祖父类构造函数,祖父类为最上级,它的构造函数和无继承关系的构造函数相同,这里不予分析  
  23. 00401229    call    @ILT+45(CFurniture::CFurniture) (00401032)  
  24. 0040122E    mov     edx,dword ptr [ebp-14h] ; 获取构造标记  
  25. 00401231    or      edx,1               ; 将构造标记置为1  
  26. 00401234    mov     dword ptr [ebp-14h],edx ; 修改构造标记  
  27. 00401237    mov     dword ptr [ebp-4],0  
  28. 0040123E    push    0               ; 压入0作为构造标记  
  29. 00401240    mov ecx,dword ptr [ebp-10h] ; 获取对象首地址作为this指针  
  30. 00401243    call    @ILT+110(CSofa::CSofa) (00401073); 调用父类构造函数  
  31. 00401248    mov     dword ptr [ebp-4],1  
  32. 0040124F    push    0               ; 压入0作为构造标记  
  33. 00401251    mov     ecx,dword ptr [ebp-10h]  
  34. 00401254    add     ecx,0Ch             ; 调整this指针  
  35. 00401257    call    @ILT+130(CBed::CBed) (00401087) ; 调用父类构造函数  
  36. 0040125C        mov     eax,dword ptr [ebp-10h]  
  37.     ; CSofaBed对应CSofa的虚表指针  
  38. 0040125F    mov     dword ptr [eax],offset CSofaBed::'vftable' (00425034)  
  39. 00401265    mov     ecx,dword ptr [ebp-10h]  
  40.     ; CSofaBed对应CBed的虚表指针  
  41. 00401268    mov     dword ptr [ecx+0Ch],offset CSofaBed::'vftable' (00425028)  
  42. 0040126F    mov     edx,dword ptr [ebp-10h] ;通过this指针和vt_offset定位到祖;父类的虚表指针  
  43. 00401272    mov     eax,dword ptr [edx+4] ; vt_offset存入eax中  
  44. 00401275    mov     ecx,dword ptr [eax+4] ; 父类虚表指针相对于vt_offset的偏移存入eax中  
  45. 00401278    mov     edx,dword ptr [ebp-10h]  
  46.     ; CSofaBed对应CFurniture的虚表指针  
  47. 0040127B    mov     dword ptr [edx+ecx+4],offset CSofaBed::'vftable' (0042501c)  
  48. m_nHeight = 6;  
  49. 00401283    mov eax,dword ptr [ebp-10h]  
  50. 00401286        mov     dword ptr [eax+1Ch],6  
  51. }  
  52. 004012B1    ret     4 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇12.4 菱形继承(4) 下一篇12.4 菱形继承(2)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: