用汇编的眼光看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的析构函数,上面的汇编代码证明了一切。



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

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式-老费

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值