构造函数的调用时机
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造函数的调用时机相关的知识,希望对你有一定的参考价值。
构造函数是C++类的重要组成部分,起着初始化对象的作用。当对象生成的时候,编译器会自动调用对象的构造函数,完成对象的初始化工作。根据对象的不同作用域和声明周期,可以将对象分为一下几种:
1.局部对象
2.堆对象
3.全局对象
4.静态对象
下面我们将以反汇编(VC6.0)的形式,查看局部对象的调用时机
#include <stdio.h> class CDemo { public: CDemo() { m_nInt = 100; } private: int m_nInt; }; int main(void) { CDemo demo; //创建一个局部对象 return 0; }
将代码反汇编后代码如下
16: int main(void) 17: { 00401020 55 push ebp 00401021 8B EC mov ebp,esp 00401023 83 EC 44 sub esp,44h 00401026 53 push ebx 00401027 56 push esi 00401028 57 push edi 00401029 8D 7D BC lea edi,[ebp-44h] 0040102C B9 11 00 00 00 mov ecx,11h 00401031 B8 CC CC CC CC mov eax,0CCCCCCCCh 00401036 F3 AB rep stos dword ptr [edi] 18: CDemo demo; //创建一个局部对象 00401038 8D 4D FC lea ecx,[ebp-4] ;将this指针保存到ecx中
0040103B E8 CA FF FF FF call @ILT+5(CDemo::CDemo) (0040100a) ;调用对象的构造函数 19: 20: 21: return 0; 00401040 33 C0 xor eax,eax 22: } 00401042 5F pop edi 00401043 5E pop esi 00401044 5B pop ebx 00401045 83 C4 44 add esp,44h 00401048 3B EC cmp ebp,esp 0040104A E8 51 00 00 00 call __chkesp (004010a0) 0040104F 8B E5 mov esp,ebp 00401051 5D pop ebp 00401052 C3 ret
根据反汇编代码可以看出,局部对象在创建以后,编译器会立即调用对象的构造函数。与调用一般成员函数一样,编译器会将this指针保存到ecx中,作为参数传递。继续单步进入构造函数,反汇编如下
3: class CDemo 4: { 5: public: 6: CDemo() 00401060 55 push ebp 00401061 8B EC mov ebp,esp 00401063 83 EC 44 sub esp,44h 00401066 53 push ebx 00401067 56 push esi 00401068 57 push edi 00401069 51 push ecx ;ecx中保存的是this指针 0040106A 8D 7D BC lea edi,[ebp-44h] 0040106D B9 11 00 00 00 mov ecx,11h 00401072 B8 CC CC CC CC mov eax,0CCCCCCCCh 00401077 F3 AB rep stos dword ptr [edi] 00401079 59 pop ecx ;还原ecx 0040107A 89 4D FC mov dword ptr [ebp-4],ecx ;将ecx存放在一个临时变量中 7: { 8: m_nInt = 100; 0040107D 8B 45 FC mov eax,dword ptr [ebp-4] ;将ecx传递给eax 00401080 C7 00 64 00 00 00 mov dword ptr [eax],64h ;相当于[this + 0],利用this指针+偏移找到第一个数据元素 9: } 00401086 8B 45 FC mov eax,dword ptr [ebp-4] ;将this指针返回 00401089 5F pop edi 0040108A 5E pop esi 0040108B 5B pop ebx 0040108C 8B E5 mov esp,ebp 0040108E 5D pop ebp 0040108F C3 ret
根据反汇编代码可以看出,C++语法虽然规定构造函数是没有返回值的,但是实际上编译器将this指针作为构造函数的返回值。
以上是关于构造函数的调用时机的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段