【 聲明:版權所有,歡迎轉載,請勿用於商業用途。 聯系信箱:feixiaoxing @163.com】
繼承是類的一個基本屬性,可是在類的繼承過程中,函數是怎麼初始化?怎麼析構的呢?我們不妨看看下面這樣的一段代碼?
copy to clipboardprint?class employee
{
public:
employee() { printf("employee()!\n");}
~employee() { printf("~employee()!\n");}
};
class manager : public employee
{
public:
manager() { printf("manager()!\n");}
~manager() { printf("~maneger()!\n");}
};
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,那麼在內存構建和析構的時候函數又是怎麼安排的呢?
copy to clipboardprint?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
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的構造和析構究竟是怎麼做的?
copy to clipboardprint?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
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的缺省構造函數,那麼析構函數呢?
copy to clipboardprint?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
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的析構函數,上面的匯編代碼證明了一切。