ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:50.12KB ,
资源ID:12581932      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12581932.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C++构造函数和析构函数机制.docx)为本站会员(b****0)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C++构造函数和析构函数机制.docx

1、C+构造函数和析构函数机制在开始之前,先做好如下准备工作:class Mammal public: Mammal() cout nmammal constructorn endl; virtual Mammal() cout nmammal desturctorn endl; public: int GetAge(void) const return itsAge; void SetAge(int newAge) itsAge = newAge; int GetWeight(void) const return itsWeight; void SetWeight(int newWeight)

2、itsWeight = newWeight; public: void Speek(void) const cout nMammal Sond!n endl ; void Speek(int spkTimes) const cout nMammal Sond:spkTimestimesn endl ; virtual void Sleep(void) const cout nMammal Sleepn endl ; protected: int itsAge; int itsWeight;class Horse : public Mammal public: Horse()cout nHors

3、e constructorn endl; virtual Horse()cout nHorse destructorn endl; public: virtual void Sleep(void) const cout nHorse Sleepn endl; ;int main(void) Mammal* mammalPtr = new Horse; delete mammalPtr; return 0;1、构造函数: Mammal* mammalPtr = new Horse;的汇编代码如下:0040121D push 0Ch0040121F call operator new (00409

4、6b0)00401224 add esp,400401227 mov dword ptr ebp-18h,eax0040122A mov dword ptr ebp-4,000401231 cmp dword ptr ebp-18h,000401235 je main+54h (00401244)00401237 mov ecx,dword ptr ebp-18h0040123A call ILT+170(Horse:Horse) (004010af)0040123F mov dword ptr ebp-24h,eax00401242 jmp main+5Bh (0040124b)004012

5、44 mov dword ptr ebp-24h,00040124B mov eax,dword ptr ebp-24h0040124E mov dword ptr ebp-14h,eax00401251 mov dword ptr ebp-4,0FFFFFFFFh00401258 mov ecx,dword ptr ebp-14h0040125B mov dword ptr ebp-10h,ecx既然是研究构造函数机制,那么先忽略掉无关内容,0040123A call ILT+170(Horse:Horse) (004010af)是这一段汇编代码在本问题中的主要内容。即,在定义一个对象时会自

6、动调用类的构造 函数。下面再来具体看Horse的构造函数是什么样的:114: Horse()cout nHorse constructorn endl;00401500 push ebp00401501 mov ebp,esp00401503 push 0FFh00401505 push offset _ehhandler$?0HorseQAEXZ (0041d989)0040150A mov eax,fs:0000000000401510 push eax00401511 mov dword ptr fs:0,esp00401518 sub esp,44h0040151B push ebx0

7、040151C push esi0040151D push edi0040151E push ecx0040151F lea edi,ebp-50h00401522 mov ecx,11h00401527 mov eax,0CCCCCCCCh0040152C rep stos dword ptr edi0040152E pop ecx0040152F mov dword ptr ebp-10h,ecx00401532 mov ecx,dword ptr ebp-10h00401535 call ILT+45(Mammal:Mammal) (00401032)0040153A mov dword

8、 ptr ebp-4,000401541 mov eax,dword ptr ebp-10h00401544 mov dword ptr eax,offset Horse:vftable (00430034)0040154A push offset ILT+70(std:endl) (0040104b)0040154F push offset string nHorse constructorn (0043001c)00401554 push offset std:cout (00434eb0)00401559 call ILT+220(std:operator) (004010e1)0040

9、155E add esp,800401561 mov ecx,eax00401563 call ILT+160(std:basic_ostreamchar,std:char_traits :operator) (004010a5)00401568 mov dword ptr ebp-4,0FFFFFFFFh0040156F mov eax,dword ptr ebp-10h00401572 mov ecx,dword ptr ebp-0Ch00401575 mov dword ptr fs:0,ecx0040157C pop edi0040157D pop esi0040157E pop eb

10、x0040157F add esp,50h00401582 cmp ebp,esp00401584 call _chkesp (00409ba0)00401589 mov esp,ebp0040158B pop ebp0040158C ret去除无关内容。仅保留函数调用:114: Horse()cout nHorse constructorn endl;00401535 call ILT+45(Mammal:Mammal) (00401032)00401559 call ILT+220(std:operator) (004010e1)00401563 call ILT+160(std:basi

11、c_ostreamchar,std:char_traits :operator) (004010a5)00401584 call _chkesp (00409ba0)0040158C ret第一个call调用了基类的构造函数;第二个call调用重载运算符;第三个call调用输出语句输出;第四个call调用栈检查函数。由此可见,Horse()cout nHorse constructorn endl;在运行时,编译器会在前面插入必要的语句来实现一些重要功能,比如说先调用基类构造函数,然后才运行用户写入的代码。2、析构函数:15: delete mammalPtr;0040125E mov edx

12、,dword ptr ebp-10h00401261 mov dword ptr ebp-20h,edx00401264 mov eax,dword ptr ebp-20h00401267 mov dword ptr ebp-1Ch,eax0040126A cmp dword ptr ebp-1Ch,00040126E je main+9Ah (0040128a)00401270 mov esi,esp00401272 push 100401274 mov ecx,dword ptr ebp-1Ch00401277 mov edx,dword ptr ecx00401279 mov ecx,d

13、word ptr ebp-1Ch0040127C call dword ptr edx0040127E cmp esi,esp00401280 call _chkesp (00409ba0)00401285 mov dword ptr ebp-28h,eax00401288 jmp main+0A1h (00401291)0040128A mov dword ptr ebp-28h,0去除无关内容。仅保留函数调用:15: delete mammalPtr;0040125E mov edx,dword ptr ebp-10h00401261 mov dword ptr ebp-20h,edx00

14、401264 mov eax,dword ptr ebp-20h00401267 mov dword ptr ebp-1Ch,eax0040126A cmp dword ptr ebp-1Ch,00040126E je main+9Ah (0040128a)00401270 mov esi,esp00401272 push 100401274 mov ecx,dword ptr ebp-1Ch00401277 mov edx,dword ptr ecx00401279 mov ecx,dword ptr ebp-1Ch0040127C call dword ptr edx00401280 ca

15、ll _chkesp (00409ba0)由于析构函数是个虚函数,所以先在虚函数表中查找出析构函数的地址,然后再对析构函数进行调用。下面再来具体看Horse的析构函数是什么样的:115: virtual Horse()cout nHorse destructorn endl;004027C0 push ebp004027C1 mov ebp,esp004027C3 push 0FFh004027C5 push offset _ehhandler$?1HorseUAEXZ (0041d9e9)004027CA mov eax,fs:00000000004027D0 push eax004027D

16、1 mov dword ptr fs:0,esp004027D8 sub esp,44h004027DB push ebx004027DC push esi004027DD push edi004027DE push ecx004027DF lea edi,ebp-50h004027E2 mov ecx,11h004027E7 mov eax,0CCCCCCCCh004027EC rep stos dword ptr edi004027EE pop ecx004027EF mov dword ptr ebp-10h,ecx004027F2 mov eax,dword ptr ebp-10h00

17、4027F5 mov dword ptr eax,offset Horse:vftable (00430034)004027FB mov dword ptr ebp-4,000402802 push offset ILT+70(std:endl) (0040104b)00402807 push offset string nHorse destructorn (004300a4)0040280C push offset std:cout (00434eb0)00402811 call ILT+220(std:operator) (004010e1)00402816 add esp,800402

18、819 mov ecx,eax0040281B call ILT+160(std:basic_ostreamchar,std:char_traits :operator) (004010a5)00402820 mov dword ptr ebp-4,0FFFFFFFFh00402827 mov ecx,dword ptr ebp-10h0040282A call ILT+120(Mammal:Mammal) (0040107d)0040282F mov ecx,dword ptr ebp-0Ch00402832 mov dword ptr fs:0,ecx00402839 pop edi004

19、0283A pop esi0040283B pop ebx0040283C add esp,50h0040283F cmp ebp,esp00402841 call _chkesp (00409ba0)00402846 mov esp,ebp00402848 pop ebp00402849 ret去除无关内容。仅保留函数调用:115: virtual Horse()cout nHorse destructorn endl; 00402811 call ILT+220(std:operator) (004010e1)0040281B call ILT+160(std:basic_ostreamc

20、har,std:char_traits :operator) (004010a5)0040282A call ILT+120(Mammal:Mammal) (0040107d)00402841 call _chkesp (00409ba0)00402849 ret第一个call调用重载运算符;第二个call调用输出函数;第三个call调用基类析构函数;第四个call调用栈检测函数,检测占空间有没有被破坏。由此可见,子类析构函数会先运行用户所写的代码,运行完了后编译器在后面插入了调用基类析构函数的指令。由此可以调用所有相关的析构函数。这是构造函数为虚函数所发生的情况。如果析构函数不是虚函数呢?1

21、、基类析构函数为虚函数,子类构造函数为非虚函数class Mammal public: Mammal() cout nmammal constructorn endl; virtual Mammal() cout nmammal desturctorn endl; public: int GetAge(void) const return itsAge; void SetAge(int newAge) itsAge = newAge; int GetWeight(void) const return itsWeight; void SetWeight(int newWeight) itsWei

22、ght = newWeight; public: void Speek(void) const cout nMammal Sond!n endl ; void Speek(int spkTimes) const cout nMammal Sond: spkTimes timesn endl ; virtual void Sleep(void) const cout nMammal Sleepn endl ; protected: int itsAge; int itsWeight;class Horse : public Mammal public: Horse()cout nHorse co

23、nstructorn endl; Horse()cout nHorse destructorn endl; public: virtual void Sleep(void) const cout nHorse Sleepn endl; ;int main(void) Mammal* mammalPtr = new Horse; delete mammalPtr; return 0;运行结果:汇编代码:15: delete mammalPtr;0040125E mov edx,dword ptr ebp-10h00401261 mov dword ptr ebp-20h,edx00401264

24、mov eax,dword ptr ebp-20h00401267 mov dword ptr ebp-1Ch,eax0040126A cmp dword ptr ebp-1Ch,00040126E je main+9Ah (0040128a)00401270 mov esi,esp00401272 push 100401274 mov ecx,dword ptr ebp-1Ch00401277 mov edx,dword ptr ecx00401279 mov ecx,dword ptr ebp-1Ch0040127C call dword ptr edx0040127E cmp esi,e

25、sp00401280 call _chkesp (00409ba0)00401285 mov dword ptr ebp-28h,eax00401288 jmp main+0A1h (00401291)0040128A mov dword ptr ebp-28h,0去除无关内容。仅保留函数调用:15: delete mammalPtr;0040125E mov edx,dword ptr ebp-10h00401261 mov dword ptr ebp-20h,edx00401264 mov eax,dword ptr ebp-20h00401267 mov dword ptr ebp-1C

26、h,eax0040126A cmp dword ptr ebp-1Ch,00040126E je main+9Ah (0040128a)00401270 mov esi,esp00401272 push 100401274 mov ecx,dword ptr ebp-1Ch00401277 mov edx,dword ptr ecx00401279 mov ecx,dword ptr ebp-1Ch0040127C call dword ptr edx00401280 call _chkesp (00409ba0)结合输出结果由此课件,子类的析构函数虽然没有在前面加virtual但是由于基类的

27、析构函数是virtual的,所以编译器自动将子类的构造函数也设置为virtual的,因此可以正常调用子类析构函数和基类析构函数。2、基类析构函数为非虚函数,子类构造函数为虚函数class Mammal public: Mammal() cout nmammal constructorn endl; Mammal() cout nmammal desturctorn endl; public: int GetAge(void) const return itsAge; void SetAge(int newAge) itsAge = newAge; int GetWeight(void) const return itsWeight; void SetWeight(int newWeight) itsWeight = newWeight; public: void Speek(void) const cout nMammal Sond!n endl ; void Speek(int spkTimes) const cout nMammal Sond: spkTimes timesn endl ; virtual void Sleep(void) const cout nMammal Sleepn endl ; protected:

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1