构造函数和析构函数出现的时机
- 局部对象
109: // 局部对象定义调用构造函数 110: 111: CNumber Number; 00C8A37D 8D 4D EC lea ecx,[Number] 00C8A380 E8 14 97 FF FF call CNumber::CNumber (0C83A99h)
局部对象的析构顺序与构造顺序相反
- 堆对象
109: // 局部对象定义调用构造函数 110: 111: CNumber Number; 00C8A385 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 112: // 申请堆对象 113: CNumber * pNumber = NULL; 00C8A38C C7 45 E0 00 00 00 00 mov dword ptr [pNumber],0 114: pNumber = new CNumber; 00C8A393 6A 04 push 4 00C8A395 E8 31 92 FF FF call operator new (0C835CBh) //运算符 new 00C8A39A 83 C4 04 add esp,4 00C8A39D 89 85 F0 FE FF FF mov dword ptr [ebp-110h],eax 00C8A3A3 C6 45 FC 01 mov byte ptr [ebp-4],1 00C8A3A7 83 BD F0 FE FF FF 00 cmp dword ptr [ebp-110h],0 //new返回的堆空间地址 00C8A3AE 74 13 je main+83h (0C8A3C3h) //为NULL则跳过构造函数 00C8A3B0 8B 8D F0 FE FF FF mov ecx,dword ptr [ebp-110h] 00C8A3B6 E8 DE 96 FF FF call CNumber::CNumber (0C83A99h) //构造函数 00C8A3BB 89 85 A0 FE FF FF mov dword ptr [ebp-160h],eax 00C8A3C1 EB 0A jmp main+8Dh (0C8A3CDh) 00C8A3C3 C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0 00C8A3CD 8B 85 A0 FE FF FF mov eax,dword ptr [ebp-160h] 00C8A3D3 89 85 FC FE FF FF mov dword ptr [ebp-104h],eax 00C8A3D9 C6 45 FC 00 mov byte ptr [ebp-4],0 00C8A3DD 8B 8D FC FE FF FF mov ecx,dword ptr [ebp-104h] 00C8A3E3 89 4D E0 mov dword ptr [pNumber],ecx 115: pNumber->m_nNumber = 2; 00C8A3E6 8B 45 E0 mov eax,dword ptr [pNumber] 00C8A3E9 C7 00 02 00 00 00 mov dword ptr [eax],2 116: printf("%d \r\n", pNumber->m_nNumber); 00C8A3EF 8B 45 E0 mov eax,dword ptr [pNumber] 00C8A3F2 8B 08 mov ecx,dword ptr [eax] 00C8A3F4 51 push ecx 00C8A3F5 68 78 5F D2 00 push offset string "%d \r\n" (0D25F78h) 00C8A3FA E8 C6 6F FF FF call _printf (0C813C5h) 00C8A3FF 83 C4 08 add esp,8 117: 118: if (pNumber != NULL) 00C8A402 83 7D E0 00 cmp dword ptr [pNumber],0 00C8A406 74 44 je main+10Ch (0C8A44Ch) 119: { 120: delete pNumber; 00C8A408 8B 45 E0 mov eax,dword ptr [pNumber] 00C8A40B 89 85 D8 FE FF FF mov dword ptr [ebp-128h],eax 00C8A411 8B 8D D8 FE FF FF mov ecx,dword ptr [ebp-128h] 00C8A417 89 8D E4 FE FF FF mov dword ptr [ebp-11Ch],ecx 00C8A41D 83 BD E4 FE FF FF 00 cmp dword ptr [ebp-11Ch],0 00C8A424 74 15 je main+0FBh (0C8A43Bh) 00C8A426 6A 01 push 1 00C8A428 8B 8D E4 FE FF FF mov ecx,dword ptr [ebp-11Ch] 00C8A42E E8 27 80 FF FF call CNumber::`scalar deleting destructor' (0C8245Ah) 00C8A433 89 85 A0 FE FF FF mov dword ptr [ebp-160h],eax 00C8A439 EB 0A jmp main+105h (0C8A445h) 00C8A43B C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0 121: pNumber = NULL; 00C8A445 C7 45 E0 00 00 00 00 mov dword ptr [pNumber],0 122: }
释放堆对象数组
125: // 释放多个堆对象 126: CNumber * pArray = new CNumber[2]; 00C8A44C 6A 0C push 0Ch 122: } 123: 124: 125: // 释放多个堆对象 126: CNumber * pArray = new CNumber[2]; 00C8A44E E8 0D 75 FF FF call operator new[] (0C81960h) 00C8A453 83 C4 04 add esp,4 00C8A456 89 85 C0 FE FF FF mov dword ptr [ebp-140h],eax 00C8A45C C6 45 FC 02 mov byte ptr [ebp-4],2 00C8A460 83 BD C0 FE FF FF 00 cmp dword ptr [ebp-140h],0 00C8A467 74 3A je main+163h (0C8A4A3h) 00C8A469 8B 85 C0 FE FF FF mov eax,dword ptr [ebp-140h] 00C8A46F C7 00 02 00 00 00 mov dword ptr [eax],2 00C8A475 68 9E 2B C8 00 push offset CNumber::~CNumber (0C82B9Eh) 00C8A47A 68 99 3A C8 00 push offset CNumber::CNumber (0C83A99h) 00C8A47F 6A 02 push 2 00C8A481 6A 04 push 4 00C8A483 8B 8D C0 FE FF FF mov ecx,dword ptr [ebp-140h] 00C8A489 83 C1 04 add ecx,4 00C8A48C 51 push ecx 00C8A48D E8 11 73 FF FF call `eh vector constructor iterator' (0C817A3h) 00C8A492 8B 95 C0 FE FF FF mov edx,dword ptr [ebp-140h] 00C8A498 83 C2 04 add edx,4 00C8A49B 89 95 A0 FE FF FF mov dword ptr [ebp-160h],edx 00C8A4A1 EB 0A jmp main+16Dh (0C8A4ADh) 00C8A4A3 C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0 00C8A4AD 8B 85 A0 FE FF FF mov eax,dword ptr [ebp-160h] 00C8A4B3 89 85 CC FE FF FF mov dword ptr [ebp-134h],eax 00C8A4B9 C6 45 FC 00 mov byte ptr [ebp-4],0 00C8A4BD 8B 8D CC FE FF FF mov ecx,dword ptr [ebp-134h] 00C8A4C3 89 4D D4 mov dword ptr [pArray],ecx 127: if (pArray != NULL) 00C8A4C6 83 7D D4 00 cmp dword ptr [pArray],0 00C8A4CA 74 44 je main+1D0h (0C8A510h) 128: { 129: delete [] pArray; 00C8A4CC 8B 45 D4 mov eax,dword ptr [pArray] 00C8A4CF 89 85 A8 FE FF FF mov dword ptr [ebp-158h],eax 00C8A4D5 8B 8D A8 FE FF FF mov ecx,dword ptr [ebp-158h] 00C8A4DB 89 8D B4 FE FF FF mov dword ptr [ebp-14Ch],ecx 00C8A4E1 83 BD B4 FE FF FF 00 cmp dword ptr [ebp-14Ch],0 00C8A4E8 74 15 je main+1BFh (0C8A4FFh) 00C8A4EA 6A 03 push 3 00C8A4EC 8B 8D B4 FE FF FF mov ecx,dword ptr [ebp-14Ch] 00C8A4F2 E8 B7 8A FF FF call CNumber::`vector deleting destructor' (0C82FAEh) 00C8A4F7 89 85 A0 FE FF FF mov dword ptr [ebp-160h],eax 00C8A4FD EB 0A jmp main+1C9h (0C8A509h) 00C8A4FF C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0 130: pArray = NULL; 00C8A509 C7 45 D4 00 00 00 00 mov dword ptr [pArray],0 131: }
- 参数对象
143: Show(MyString); 002CA529 51 push ecx //开辟4字节参数对象空间 002CA52A 8B CC mov ecx,esp 002CA52C 89 A5 90 FE FF FF mov dword ptr [ebp-170h],esp 002CA532 8D 45 C8 lea eax,[MyString] 002CA535 50 push eax 002CA536 E8 48 74 FF FF call CMyString::CMyString (02C1983h) //调用拷贝构造函数,将实参拷贝到开辟的参数对象空间中去。 002CA53B E8 DB 90 FF FF call Show (02C361Bh) 002CA540 83 C4 04 add esp,4
参数对象的析构函数
64: void Show(CMyString MyString){ 002CA230 55 push ebp 002CA231 8B EC mov ebp,esp 002CA233 81 EC C0 00 00 00 sub esp,0C0h 002CA239 53 push ebx 002CA23A 56 push esi 002CA23B 57 push edi 002CA23C 8D BD 40 FF FF FF lea edi,[ebp-0C0h] 002CA242 B9 30 00 00 00 mov ecx,30h 002CA247 B8 CC CC CC CC mov eax,0CCCCCCCCh 002CA24C F3 AB rep stos dword ptr es:[edi] 65: printf(MyString.m_pString); 002CA24E 8B 45 08 mov eax,dword ptr [MyString] 002CA251 50 push eax 002CA252 E8 6E 71 FF FF call _printf (02C13C5h) 002CA257 83 C4 04 add esp,4 66: } 002CA25A 8D 4D 08 lea ecx,[MyString] 002CA25D E8 A1 88 FF FF call CMyString::~CMyString (02C2B03h) //在函数内,将进入函数前拷贝构造的参数对象析构。 002CA262 5F pop edi 002CA263 5E pop esi 002CA264 5B pop ebx 002CA265 81 C4 C0 00 00 00 add esp,0C0h 002CA26B 3B EC cmp ebp,esp 002CA26D E8 74 8C FF FF call __RTC_CheckEsp (02C2EE6h) 002CA272 8B E5 mov esp,ebp 002CA274 5D pop ebp 002CA275 C3 ret
- 返回对象
145: // 返回值为对象类型的拷贝构造使用 146: CMyString MyString1 = GetMyString(); 002CA543 8D 45 BC lea eax,[MyString1] 002CA546 50 push eax 002CA547 E8 32 97 FF FF call GetMyString (02C3C7Eh) 002CA54C 83 C4 04 add esp,4
在返回对象的函数GetMyString内部,会调用拷贝函数,将函数内的局部对象拷贝到进入函数前准备的地址空间中。之后调用析构函数,释放函数内产生的局部对象。
68: // 返回对象 69: CMyString GetMyString() 70: { 002C9F40 55 push ebp 002C9F41 8B EC mov ebp,esp 002C9F43 6A FF push 0FFFFFFFFh 002C9F45 68 38 2B 36 00 push 362B38h 002C9F4A 64 A1 00 00 00 00 mov eax,dword ptr fs:[00000000h] 002C9F50 50 push eax 002C9F51 81 EC D8 00 00 00 sub esp,0D8h 002C9F57 53 push ebx 002C9F58 56 push esi 002C9F59 57 push edi 002C9F5A 8D BD 1C FF FF FF lea edi,[ebp-0E4h] 002C9F60 B9 36 00 00 00 mov ecx,36h 002C9F65 B8 CC CC CC CC mov eax,0CCCCCCCCh 002C9F6A F3 AB rep stos dword ptr es:[edi] 002C9F6C A1 08 A0 38 00 mov eax,dword ptr [__security_cookie (038A008h)] 002C9F71 33 C5 xor eax,ebp 002C9F73 50 push eax 002C9F74 8D 45 F4 lea eax,[ebp-0Ch] 002C9F77 64 A3 00 00 00 00 mov dword ptr fs:[00000000h],eax 002C9F7D C7 85 20 FF FF FF 00 00 00 00 mov dword ptr [ebp-0E0h],0 71: CMyString MyString; 002C9F87 8D 4D EC lea ecx,[MyString] 002C9F8A E8 74 7C FF FF call CMyString::CMyString (02C1C03h)//局部对象,构造函数 002C9F8F C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 72: MyString.SetString("World"); 002C9F96 68 70 5F 36 00 push offset string "World" (0365F70h) 002C9F9B 8D 4D EC lea ecx,[MyString] 002C9F9E E8 44 98 FF FF call CMyString::SetString (02C37E7h) 73: return MyString; 002C9FA3 8D 45 EC lea eax,[MyString] 002C9FA6 50 push eax 002C9FA7 8B 4D 08 mov ecx,dword ptr [ebp+8] 002C9FAA E8 D4 79 FF FF call CMyString::CMyString (02C1983h)//调用拷贝构造函数 002C9FAF 8B 8D 20 FF FF FF mov ecx,dword ptr [ebp-0E0h] 002C9FB5 83 C9 01 or ecx,1 002C9FB8 89 8D 20 FF FF FF mov dword ptr [ebp-0E0h],ecx 002C9FBE C7 45 FC FF FF FF FF mov dword ptr [ebp-4],0FFFFFFFFh 002C9FC5 8D 4D EC lea ecx,[MyString] 002C9FC8 E8 36 8B FF FF call CMyString::~CMyString (02C2B03h) //函数内的局部对象 析构函数 002C9FCD 8B 45 08 mov eax,dword ptr [ebp+8] 74: }
- 全局对象
全局对象的构造函数在启动函数中调用。析构函数在main函数退出时调用。
- 静态对象
静态对象构造函数与析构函数调用的时机相同。