C++构造函数和析构函数机制.docx
- 文档编号:12581932
- 上传时间:2023-04-20
- 格式:DOCX
- 页数:29
- 大小:50.12KB
C++构造函数和析构函数机制.docx
《C++构造函数和析构函数机制.docx》由会员分享,可在线阅读,更多相关《C++构造函数和析构函数机制.docx(29页珍藏版)》请在冰豆网上搜索。
C++构造函数和析构函数机制
在开始之前,先做好如下准备工作:
classMammal
{
public:
Mammal()
{
cout<<"\nmammalconstructor\n"< } virtual~Mammal() { cout<<"\nmammaldesturctor\n"< } public: intGetAge(void)const { returnitsAge; } voidSetAge(intnewAge) { itsAge=newAge; } intGetWeight(void)const { returnitsWeight; } voidSetWeight(intnewWeight) { itsWeight=newWeight; } public: voidSpeek(void)const { cout<<"\nMammalSond! \n"< } voidSpeek(intspkTimes)const { cout<<"\nMammalSond: "< } virtualvoidSleep(void)const { cout<<"\nMammalSleep\n"< } protected: intitsAge; intitsWeight; }; classHorse: publicMammal { public: Horse(){cout<<"\nHorseconstructor\n"< virtual~Horse(){cout<<"\nHorsedestructor\n"< public: virtualvoidSleep(void)const { cout<<"\nHorseSleep\n"< } }; intmain(void) { Mammal*mammalPtr=newHorse; deletemammalPtr; return0; } 1、构造函数: Mammal*mammalPtr=newHorse;的汇编代码如下: 0040121Dpush0Ch 0040121Fcalloperatornew(004096b0) 00401224addesp,4 00401227movdwordptr[ebp-18h],eax 0040122Amovdwordptr[ebp-4],0 00401231cmpdwordptr[ebp-18h],0 00401235jemain+54h(00401244) 00401237movecx,dwordptr[ebp-18h] 0040123Acall@ILT+170(Horse: : Horse)(004010af) 0040123Fmovdwordptr[ebp-24h],eax 00401242jmpmain+5Bh(0040124b) 00401244movdwordptr[ebp-24h],0 0040124Bmoveax,dwordptr[ebp-24h] 0040124Emovdwordptr[ebp-14h],eax 00401251movdwordptr[ebp-4],0FFFFFFFFh 00401258movecx,dwordptr[ebp-14h] 0040125Bmovdwordptr[ebp-10h],ecx 既然是研究构造函数机制,那么先忽略掉无关内容, 0040123Acall@ILT+170(Horse: : Horse)(004010af) 是这一段汇编代码在本问题中的主要内容。 即,在定义一个对象时会自动调用类的构造函数。 下面再来具体看Horse的构造函数是什么样的: 114: Horse(){cout<<"\nHorseconstructor\n"< 00401500pushebp 00401501movebp,esp 00401503push0FFh 00401505pushoffset__ehhandler$? ? 0Horse@@QAE@XZ(0041d989) 0040150Amoveax,fs: [00000000] 00401510pusheax 00401511movdwordptrfs: [0],esp 00401518subesp,44h 0040151Bpushebx 0040151Cpushesi 0040151Dpushedi 0040151Epushecx 0040151Fleaedi,[ebp-50h] 00401522movecx,11h 00401527moveax,0CCCCCCCCh 0040152Crepstosdwordptr[edi] 0040152Epopecx 0040152Fmovdwordptr[ebp-10h],ecx 00401532movecx,dwordptr[ebp-10h] 00401535call@ILT+45(Mammal: : Mammal)(00401032) 0040153Amovdwordptr[ebp-4],0 00401541moveax,dwordptr[ebp-10h] 00401544movdwordptr[eax],offsetHorse: : `vftable'(00430034) 0040154Apushoffset@ILT+70(std: : endl)(0040104b) 0040154Fpushoffsetstring"\nHorseconstructor\n"(0043001c) 00401554pushoffsetstd: : cout(00434eb0) 00401559call@ILT+220(std: : operator<<)(004010e1) 0040155Eaddesp,8 00401561movecx,eax 00401563call@ILT+160(std: : basic_ostream : char_traits : operator<<)(004010a5) 00401568movdwordptr[ebp-4],0FFFFFFFFh 0040156Fmoveax,dwordptr[ebp-10h] 00401572movecx,dwordptr[ebp-0Ch] 00401575movdwordptrfs: [0],ecx 0040157Cpopedi 0040157Dpopesi 0040157Epopebx 0040157Faddesp,50h 00401582cmpebp,esp 00401584call__chkesp(00409ba0) 00401589movesp,ebp 0040158Bpopebp 0040158Cret 去除无关内容。 仅保留函数调用: 114: Horse(){cout<<"\nHorseconstructor\n"< 00401535call@ILT+45(Mammal: : Mammal)(00401032) 00401559call@ILT+220(std: : operator<<)(004010e1) 00401563call@ILT+160(std: : basic_ostream : char_traits : operator<<)(004010a5) 00401584call__chkesp(00409ba0) 0040158Cret 第一个call调用了基类的构造函数;第二个call调用重载运算符;第三个call调用输出语句输出;第四个call调用栈检查函数。 由此可见,Horse(){cout<<"\nHorseconstructor\n"< 2、析构函数: 15: deletemammalPtr; 0040125Emovedx,dwordptr[ebp-10h] 00401261movdwordptr[ebp-20h],edx 00401264moveax,dwordptr[ebp-20h] 00401267movdwordptr[ebp-1Ch],eax 0040126Acmpdwordptr[ebp-1Ch],0 0040126Ejemain+9Ah(0040128a) 00401270movesi,esp 00401272push1 00401274movecx,dwordptr[ebp-1Ch] 00401277movedx,dwordptr[ecx] 00401279movecx,dwordptr[ebp-1Ch] 0040127Ccalldwordptr[edx] 0040127Ecmpesi,esp 00401280call__chkesp(00409ba0) 00401285movdwordptr[ebp-28h],eax 00401288jmpmain+0A1h(00401291) 0040128Amovdwordptr[ebp-28h],0 去除无关内容。 仅保留函数调用: 15: deletemammalPtr; 0040125Emovedx,dwordptr[ebp-10h] 00401261movdwordptr[ebp-20h],edx 00401264moveax,dwordptr[ebp-20h] 00401267movdwordptr[ebp-1Ch],eax 0040126Acmpdwordptr[ebp-1Ch],0 0040126Ejemain+9Ah(0040128a) 00401270movesi,esp 00401272push1 00401274movecx,dwordptr[ebp-1Ch] 00401277movedx,dwordptr[ecx] 00401279movecx,dwordptr[ebp-1Ch] 0040127Ccalldwordptr[edx] 00401280call__chkesp(00409ba0) 由于析构函数是个虚函数,所以先在虚函数表中查找出析构函数的地址,然后再对析构函数进行调用。 下面再来具体看Horse的析构函数是什么样的: 115: virtual~Horse(){cout<<"\nHorsedestructor\n"< 004027C0pushebp 004027C1movebp,esp 004027C3push0FFh 004027C5pushoffset__ehhandler$? ? 1Horse@@UAE@XZ(0041d9e9) 004027CAmoveax,fs: [00000000] 004027D0pusheax 004027D1movdwordptrfs: [0],esp 004027D8subesp,44h 004027DBpushebx 004027DCpushesi 004027DDpushedi 004027DEpushecx 004027DFleaedi,[ebp-50h] 004027E2movecx,11h 004027E7moveax,0CCCCCCCCh 004027ECrepstosdwordptr[edi] 004027EEpopecx 004027EFmovdwordptr[ebp-10h],ecx 004027F2moveax,dwordptr[ebp-10h] 004027F5movdwordptr[eax],offsetHorse: : `vftable'(00430034) 004027FBmovdwordptr[ebp-4],0 00402802pushoffset@ILT+70(std: : endl)(0040104b) 00402807pushoffsetstring"\nHorsedestructor\n"(004300a4) 0040280Cpushoffsetstd: : cout(00434eb0) 00402811call@ILT+220(std: : operator<<)(004010e1) 00402816addesp,8 00402819movecx,eax 0040281Bcall@ILT+160(std: : basic_ostream : char_traits : operator<<)(004010a5) 00402820movdwordptr[ebp-4],0FFFFFFFFh 00402827movecx,dwordptr[ebp-10h] 0040282Acall@ILT+120(Mammal: : ~Mammal)(0040107d) 0040282Fmovecx,dwordptr[ebp-0Ch] 00402832movdwordptrfs: [0],ecx 00402839popedi 0040283Apopesi 0040283Bpopebx 0040283Caddesp,50h 0040283Fcmpebp,esp 00402841call__chkesp(00409ba0) 00402846movesp,ebp 00402848popebp 00402849ret 去除无关内容。 仅保留函数调用: 115: virtual~Horse(){cout<<"\nHorsedestructor\n"< 00402811call@ILT+220(std: : operator<<)(004010e1) 0040281Bcall@ILT+160(std: : basic_ostream : char_traits : operator<<)(004010a5) 0040282Acall@ILT+120(Mammal: : ~Mammal)(0040107d) 00402841call__chkesp(00409ba0) 00402849ret 第一个call调用重载运算符;第二个call调用输出函数;第三个call调用基类析构函数;第四个call调用栈检测函数,检测占空间有没有被破坏。 由此可见,子类析构函数会先运行用户所写的代码,运行完了后编译器在后面插入了调用基类析构函数的指令。 由此可以调用所有相关的析构函数。 这是构造函数为虚函数所发生的情况。 如果析构函数不是虚函数呢? 1、基类析构函数为虚函数,子类构造函数为非虚函数 classMammal { public: Mammal() { cout<<"\nmammalconstructor\n"< } virtual~Mammal() { cout<<"\nmammaldesturctor\n"< } public: intGetAge(void)const { returnitsAge; } voidSetAge(intnewAge) { itsAge=newAge; } intGetWeight(void)const { returnitsWeight; } voidSetWeight(intnewWeight) { itsWeight=newWeight; } public: voidSpeek(void)const { cout<<"\nMammalSond! \n"< } voidSpeek(intspkTimes)const { cout<<"\nMammalSond: "< } virtualvoidSleep(void)const { cout<<"\nMammalSleep\n"< } protected: intitsAge; intitsWeight; }; classHorse: publicMammal { public: Horse(){cout<<"\nHorseconstructor\n"< ~Horse(){cout<<"\nHorsedestructor\n"< public: virtualvoidSleep(void)const { cout<<"\nHorseSleep\n"< } }; intmain(void) { Mammal*mammalPtr=newHorse; deletemammalPtr; return0; } 运行结果: 汇编代码: 15: deletemammalPtr; 0040125Emovedx,dwordptr[ebp-10h] 00401261movdwordptr[ebp-20h],edx 00401264moveax,dwordptr[ebp-20h] 00401267movdwordptr[ebp-1Ch],eax 0040126Acmpdwordptr[ebp-1Ch],0 0040126Ejemain+9Ah(0040128a) 00401270movesi,esp 00401272push1 00401274movecx,dwordptr[ebp-1Ch] 00401277movedx,dwordptr[ecx] 00401279movecx,dwordptr[ebp-1Ch] 0040127Ccalldwordptr[edx] 0040127Ecmpesi,esp 00401280call__chkesp(00409ba0) 00401285movdwordptr[ebp-28h],eax 00401288jmpmain+0A1h(00401291) 0040128Amovdwordptr[ebp-28h],0 去除无关内容。 仅保留函数调用: 15: deletemammalPtr; 0040125Emovedx,dwordptr[ebp-10h] 00401261movdwordptr[ebp-20h],edx 00401264moveax,dwordptr[ebp-20h] 00401267movdwordptr[ebp-1Ch],eax 0040126Acmpdwordptr[ebp-1Ch],0 0040126Ejemain+9Ah(0040128a) 00401270movesi,esp 00401272push1 00401274movecx,dwordptr[ebp-1Ch] 00401277movedx,dwordptr[ecx] 00401279movecx,dwordptr[ebp-1Ch] 0040127Ccalldwordptr[edx] 00401280call__chkesp(00409ba0) 结合输出结果由此课件,子类的析构函数虽然没有在前面加virtual但是由于基类的析构函数是virtual的,所以编译器自动将子类的构造函数也设置为virtual的,因此可以正常调用子类析构函数和基类析构函数。 2、基类析构函数为非虚函数,子类构造函数为虚函数 classMammal { public: Mammal() { cout<<"\nmammalconstructor\n"< } ~Mammal() { cout<<"\nmammaldesturctor\n"< } public: intGetAge(void)const { returnitsAge; } voidSetAge(intnewAge) { itsAge=newAge; } intGetWeight(void)const { returnitsWeight; } voidSetWeight(intnewWeight) { itsWeight=newWeight; } public: voidSpeek(void)const { cout<<"\nMammalSond! \n"< } voidSpeek(intspkTimes)const { cout<<"\nMammalSond: "< } virtualvoidSleep(void)const { cout<<"\nMammalSleep\n"< } protected:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 构造 函数 机制
![提示](https://static.bdocx.com/images/bang_tan.gif)