学习C++反汇编-多继承

来源:互联网 发布:易语言界面源码 编辑:程序博客网 时间:2024/06/11 05:19

C++源代码:

#include<iostream>class CSofa{public:CSofa(){Color = 2;}virtual ~CSofa(){printf("virtual ~CSofa()\r\n");}virtual int GetColor(){return Color;}virtual void SitDown(){printf("sit and relax\r\n");}protected:int Color;};class CBed{public:CBed(){Length = 4;Width = 5;}virtual ~CBed(){printf("virtual ~CBed()\r\n");}virtual int GetArea(){return Length*Width;}virtual void Sleep(){printf("go to sleep\r\n");}protected:int Length;int Width;};class CSofaBed :public CSofa, public CBed{public:CSofaBed(){Height = 4;}virtual ~CSofaBed(){printf("virtual ~CSofaBed()\r\n");}virtual void SitDown(){printf("sit and relax on the sofa bed\r\n");}virtual void Sleep(){printf("go to sleep on the sofa bed\r\n");}virtual int GetHeight(){return Height;}protected:int Height;};int main(){CSofaBed SofaBed;}
生成的汇编代码:

class CSofaBed :public CSofa, public CBed{public:CSofaBed()003018B0  push        ebp  003018B1  mov         ebp,esp  003018B3  push        0FFFFFFFFh  003018B5  push        3064C8h  003018BA  mov         eax,dword ptr fs:[00000000h]  003018C0  push        eax  003018C1  sub         esp,0CCh  003018C7  push        ebx  003018C8  push        esi  003018C9  push        edi  003018CA  push        ecx  003018CB  lea         edi,[ebp-0D8h]  003018D1  mov         ecx,33h  003018D6  mov         eax,0CCCCCCCCh  003018DB  rep stos    dword ptr es:[edi]  003018DD  pop         ecx 003018DE  mov         eax,dword ptr ds:[0030B004h]  003018E3  xor         eax,ebp  003018E5  push        eax  003018E6  lea         eax,[ebp-0Ch]  003018E9  mov         dword ptr fs:[00000000h],eax  003018EF  mov         dword ptr [this],ecx  {003018F2  mov         ecx,dword ptr [this] 以对象首地址作为this指针 003018F5  call        CSofa::CSofa (030103Ch) 调用沙发类构造函数{003018FA  mov         dword ptr [ebp-4],0  00301901  mov         ecx,dword ptr [this]  00301904  add         ecx,8 将this指针调整到第二个虚表指针地址处00301907  call        CBed::CBed (03011DBh) 调用床类构造函数0030190C  mov         eax,dword ptr [this]  0030190F  mov         dword ptr [eax],308BB0h 设置虚表指针00301915  mov         eax,dword ptr [this]  00301918  mov         dword ptr [eax+8],308BC8h 设置虚表指针Height = 4;0030191F  mov         eax,dword ptr [this]  00301922  mov         dword ptr [eax+14h],4  }virtual ~CSofaBed(){001C1A40  push        ebp  001C1A41  mov         ebp,esp  001C1A43  sub         esp,0CCh  001C1A49  push        ebx  001C1A4A  push        esi  001C1A4B  push        edi  001C1A4C  push        ecx  001C1A4D  lea         edi,[ebp-0CCh]  001C1A53  mov         ecx,33h  001C1A58  mov         eax,0CCCCCCCCh  001C1A5D  rep stos    dword ptr es:[edi]  001C1A5F  pop         ecx  001C1A60  mov         dword ptr [this],ecx  001C1A63  mov         eax,dword ptr [this]  001C1A66  mov         dword ptr [eax],1C8BB0h  001C1A6C  mov         eax,dword ptr [this]  001C1A6F  mov         dword ptr [eax+8],1C8BC8h 将两个虚表指针设置为各个父类的虚表首地址  printf("virtual ~CSofaBed()\r\n");001C1A76  push        1C8BD8h  001C1A7B  call        _printf (01C13A2h)  001C1A80  add         esp,4  }001C1A83  mov         ecx,dword ptr [this]  001C1A86  add         ecx,8  001C1A89  call        CBed::~CBed (01C1069h)  001C1A8E  mov         ecx,dword ptr [this]  }001C1A91  call        CSofa::~CSofa (01C1091h)  001C1A96  pop         edi  001C1A97  pop         esi  001C1A98  pop         ebx  001C1A99  add         esp,0CCh  001C1A9F  cmp         ebp,esp  001C1AA1  call        __RTC_CheckEsp (01C116Dh)  001C1AA6  mov         esp,ebp  001C1AA8  pop         ebp  001C1AA9  ret
在子类的构造过程中,根据继承关系的顺序,首先调用了父类CSofa的构造函数。在调用另一个父类CBed时,并不是直接将对象的首地址作为this指针传递,而是向后调整了父类CSofa的长度,以调整后的地址值作为this指针,最后再调用父类CBed的构造函数。由于有了两个父类,因此子类在继承时也将它们的虚表指针一起继承了过来,也就有了两个虚表指针。在对父类进行析构时,由于具有多个父类,调用各个父类的析构函数时传递的首地址将有所不同,编译器会根据每个父类在对象中占用的空间位置,对应地传入各个父类部分的首地址作为this指针。


0 0
原创粉丝点击