学习C++反汇编-多继承
2016-03-06 15:26
549 查看
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指针。
相关文章推荐
- C++中const修饰二级指针(从类型‘int**’到类型‘const int**’的转换无效)
- C语言实现使用动态数组来构造栈结构
- CAF(C++ actor framework)使用随笔(延迟发送,消息转发,消息优先级)(四)
- C/C++基础-001
- C++primer plus 编程练习10.10
- C语言中的static 详细分析
- C/C++学习之基础-001
- C++11中值得关注的几大变化
- c++中的继承和组合
- c++拷贝构造函数
- 【HPU】[1015]【C语言训练】列出最简真分数序列
- c++初始化函数列表
- C/C++ 内存对齐
- #define和typedef的区别
- C++扬帆远航——1
- VC++6.0新认识
- VC++error LNK2001: unresolved external symbol的解决方法
- OC语言BLOCK和协议
- C++ 中的类型转换函数
- 【HPU】[1014]【C语言训练】亲密数