程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 用匯編的眼光看C++(之類繼承)

用匯編的眼光看C++(之類繼承)

編輯:C++入門知識

 

【 聲明:版權所有,歡迎轉載,請勿用於商業用途。  聯系信箱: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的析構函數,上面的匯編代碼證明了一切。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved