用汇编的眼光看C++(之类继承)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】


继承是类的一个基本属性,可是在类的继承过程中,函数是怎么初始化?怎么析构的呢?我们不妨看看下面这样的一段代码?

class employee { public: employee() { printf("employee()!\n");} ~employee() { printf("~employee()!\n");} }; class manager : public employee { public: manager() { printf("manager()!\n");} ~manager() { printf("~maneger()!\n");} }; 看到上面的代码,相信大家也明白了,我们定义了这样一个类。基类是empoyee,继承类是manager。我们看到manager是一种特殊的employee,那么在内存构建和析构的时候函数又是怎么安排的呢?

74: manager m; 00401268 lea ecx,[ebp-4] 0040126B call @ILT+60(manager::manager) (00401041) 75: } 00401270 lea ecx,[ebp-4] 00401273 call @ILT+0(manager::~manager) (00401005) 00401278 pop edi 00401279 pop esi 0040127A pop ebx 0040127B add esp,44h 0040127E cmp ebp,esp 00401280 call __chkesp (00408760) 00401285 mov esp,ebp 00401287 pop ebp 我们发现manager的构造和析构其实也简单。构造函数其实就是在变量出现的时候进行构造。那什么时候析构呢?也就在函数快结束的时候进行析构。下面我们可以进一步讨论在manager的构造和析构究竟是怎么做的?

65: class manager : public employee 66: { 67: public: 68: manager() { printf("manager()!\n");} 004012A0 push ebp 004012A1 mov ebp,esp 004012A3 sub esp,44h 004012A6 push ebx 004012A7 push esi 004012A8 push edi 004012A9 push ecx 004012AA lea edi,[ebp-44h] 004012AD mov ecx,11h 004012B2 mov eax,0CCCCCCCCh 004012B7 rep stos dword ptr [edi] 004012B9 pop ecx 004012BA mov dword ptr [ebp-4],ecx 004012BD mov ecx,dword ptr [ebp-4] 004012C0 call @ILT+40(employee::employee) (0040102d) 004012C5 push offset string "manager()!\n" (00431020) 004012CA call printf (004086e0) 004012CF add esp,4 004012D2 mov eax,dword ptr [ebp-4] 004012D5 pop edi 004012D6 pop esi 004012D7 pop ebx 004012D8 add esp,44h 004012DB cmp ebp,esp 004012DD call __chkesp (00408760) 004012E2 mov esp,ebp 004012E4 pop ebp 004012E5 ret 我们发现,manager的构造里面添加了employee的缺省构造函数,那么析构函数呢?

69: ~manager() { printf("~maneger()!\n");} 00401350 push ebp 00401351 mov ebp,esp 00401353 sub esp,44h 00401356 push ebx 00401357 push esi 00401358 push edi 00401359 push ecx 0040135A lea edi,[ebp-44h] 0040135D mov ecx,11h 00401362 mov eax,0CCCCCCCCh 00401367 rep stos dword ptr [edi] 00401369 pop ecx 0040136A mov dword ptr [ebp-4],ecx 0040136D push offset string "~maneger()!\n" (00431040) 00401372 call printf (004086e0) 00401377 add esp,4 0040137A mov ecx,dword ptr [ebp-4] 0040137D call @ILT+5(employee::~employee) (0040100a) 00401382 pop edi 00401383 pop esi 00401384 pop ebx 00401385 add esp,44h 00401388 cmp ebp,esp 0040138A call __chkesp (00408760) 0040138F mov esp,ebp 00401391 pop ebp 00401392 ret 我们发现,manager构造的时候employee率先构造,然后打印manager;析构的时候,恰恰相反,manager首先析构自己,然后在再调用employee的析构函数,上面的汇编代码证明了一切。



【预告:下面主要讨论类的虚函数】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值