构造函数和析构函数出现的时机

  • 局部对象
   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函数退出时调用。

  • 静态对象

静态对象构造函数与析构函数调用的时机相同。

c++ 反汇编 构造函数和析构函数的更多相关文章

  1. 内存的分配VS回收&构造函数VS析构函数

    之前有一个问题一直困扰着我,就是一个变量出了作用域,我以为这个变量的内存就被回收了,其实不是这样的,昨天问了一个高手,才豁然开朗,自己在看相关代码的反汇编代码,才知道原来真是这样就.这个问题,我想简单 ...

  2. .NET 基础 一步步 一幕幕[面向对象之构造函数、析构函数]

    构造函数.析构函数 构造函数: 语法: //无参的构造函数 [访问修饰符] 函数名() :函数名必须与类名相同. //有参的构造函数 [访问修饰符] 函数名(参数列表):函数名必须与类名相同. 作用: ...

  3. 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)

    [源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...

  4. C++构造函数、析构函数与抛出异常

    [本文链接] http://www.cnblogs.com/hellogiser/p/constructor-destructor-exceptions.html [问题] 构造函数可以抛出异常么?析 ...

  5. python中的构造函数和析构函数

    python中的特殊方法,其中两个,构造函数和析构函数的作用: 比说“__init__”这个构造函数,具有初始化的作用,也就是当该类被实例化的时候就会执行该函数.那么我们就可以把要先初始化的属性放到这 ...

  6. C++C++中构造函数与析构函数的调用顺序

    http://blog.csdn.net/xw13106209/article/details/6899370 1.参考文献 参考1: C++继承中构造函数.析构函数调用顺序及虚函数的动态绑定 参考2 ...

  7. php 的 构造函数 和 析构函数

    构造函数 在C++ java里的应用及其普遍,今天好好研究了一下 php 的 构造函数 和 析构函数 构造函数 和 析构函数 构造函数 void __construct ([ mixed $args ...

  8. C++-理解构造函数、析构函数执行顺序

    先初始化序列中的函数调用,如果基类构造函数为非引用传递,则引起参数的拷贝构造 再: 先类内的成员构造函数(拷贝/默认),再类的构造函数:先基类,再派生类: 本文主要说明对象创建时构造函数的执行顺序,对 ...

  9. C++学习之类的构造函数、析构函数

    在C++的类中,都会有一个或多个构造函数.一个析构函数.一个赋值运算操作符.即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数.一个析构函数和一个赋值运算操作符.例如: //声明 ...

随机推荐

  1. google 人机身份验证

    google 人机身份验证 Are you a robot? Introducing "No CAPTCHA reCAPTCHA" https://googleonlinesecu ...

  2. 从GitHub Jobs! 看技术发展趋势! 程序员进阶必备!

    0. https://jobs.github.com/positions GitHub Jobs: 1. https://jobs.github.com/positions/38bb8dc8-b5b4 ...

  3. 使用 js 实现一个简易版的 vue 框架

    使用 js 实现一个简易版的 vue 框架 具有挑战性的前端面试题 refs https://www.infoq.cn/article/0NUjpxGrqRX6Ss01BLLE xgqfrms 201 ...

  4. React components render order All In One

    React components render order All In One components render order / components lifecycle DOM tree ren ...

  5. code magic

    code magic CI/CD for mobile app projects https://codemagic.io https://codemagic.io/apps flutter http ...

  6. Windows 10 滚动截图工具

    Windows 10 滚动截图工具 Edge & Note & Clip https://www.runoob.com/docker/docker-architecture.html ...

  7. V8 & ECMAScript & ES-Next

    V8 & ECMAScript & ES-Next ES6, ES7, ES8, ES9, ES10, ES11, ES2015, ES2016, ES2017, ES2018, ES ...

  8. react UI 框架对比

    传送门  https://blog.csdn.net/qiqingjin/article/details/79219206 点击

  9. 看超额担保免信任的NGK DeFi 乐高如何打造下一个千倍币?

    2020年中,DeFi的高收益率吸引了大量热钱涌入,DeFi总锁仓量破百亿美金.如今,流动性挖矿的热潮暂时停歇,但对于 NGK DeFi项目来说,它背后的演变进化从未停止. 免信任是 NGK DeFi ...

  10. 【转】ICP算法(Iterative Closest Point迭代最近点算法)

    原文网址:https://www.cnblogs.com/sddai/p/6129437.html.转载主要方便随时可以查看,如有版权要求请及时联系. 最近在做点云匹配,需要用c++实现ICP算法,下 ...