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

用匯編的眼光看C++(之class構造、析構)

編輯:C++入門知識

 

【 聲明:版權所有,歡迎轉載,請勿用於商業用途。  聯系信箱:feixiaoxing @163.com】 

 

 

 

 

    前面我們討論基本上都是C語言的內容,還沒有真正觸及到C++的相關知識。從這篇博客之後,我們將會更多觸及類的內容。類的屬性很多,今天我們討論主要就是構造函數、析構函數。

 

   

 

    (1)如果沒有構造函數、析構函數呢?

 

 

copy to clipboardprint?class apple 

public: 

    void print() const {return;} 

}; 

class apple

{

public:

       void print() const {return;}

};

 

    雖然這個類沒有什麼意義,但是如果用sizeof計算一下大小的話,我們發現它還是占了一個字節。那麼如果有一個apple的變量呢?為了讓apple的變量有意義,我們嘗試做一個改變:

 

 

copy to clipboardprint?66:       apple a; 

67:       a.print(); 

00401248   lea         ecx,[ebp-4] 

0040124B   call        @ILT+0(apple::print) (00401005) 

68:       return; 

69:   } 

66:       apple a;

67:       a.print();

00401248   lea         ecx,[ebp-4]

0040124B   call        @ILT+0(apple::print) (00401005)

68:       return;

69:   }

    我們看到,堆棧分配了四個字節空間給a,就是ebp下面的一個字節。

 

 

 

 

    (2) 析構函數什麼時候調用?

 

 

copy to clipboardprint?class apple 

public: 

    apple() {printf("apple()!\n");} 

    ~apple() {printf("~apple()!\n");} 

    void print() const {return;} 

}; 

class apple

{

public:

       apple() {printf("apple()!\n");}

       ~apple() {printf("~apple()!\n");}

       void print() const {return;}

};    如果調用呢,我們可以做一個測試環境,如下所示:

 

 

copy to clipboardprint?68:       apple a; 

0040126D   lea         ecx,[ebp-10h] 

00401270   call        @ILT+65(apple::apple) (00401046) 

00401275   mov         dword ptr [ebp-4],0 

69:       { 

70:           apple b; 

0040127C   lea         ecx,[b] 

0040127F   call        @ILT+65(apple::apple) (00401046) 

71:       } 

00401284   lea         ecx,[b] 

00401287   call        @ILT+0(apple::~apple) (00401005) 

0040128C   mov         dword ptr [ebp-4],0FFFFFFFFh 

72:   } 

00401293   lea         ecx,[ebp-10h] 

00401296   call        @ILT+0(apple::~apple) (00401005) 

0040129B   mov         ecx,dword ptr [ebp-0Ch] 

0040129E   mov         dword ptr fs:[0],ecx 

68:       apple a;

0040126D   lea         ecx,[ebp-10h]

00401270   call        @ILT+65(apple::apple) (00401046)

00401275   mov         dword ptr [ebp-4],0

69:       {

70:           apple b;

0040127C   lea         ecx,[b]

0040127F   call        @ILT+65(apple::apple) (00401046)

71:       }

00401284   lea         ecx,[b]

00401287   call        @ILT+0(apple::~apple) (00401005)

0040128C   mov         dword ptr [ebp-4],0FFFFFFFFh

72:   }

00401293   lea         ecx,[ebp-10h]

00401296   call        @ILT+0(apple::~apple) (00401005)

0040129B   mov         ecx,dword ptr [ebp-0Ch]

0040129E   mov         dword ptr fs:[0],ecx

    我們看到,只要出了作用域,析構函數就會自動會被調用。

 

 

 

 

    (3)如果是new調用類,析構函數會自動調用嗎?

 

    不會。

 

 

 

 

    (4)構造函數、析構函數的本質?

 

    我們知道在函數中的臨時變量在堆棧裡面應用的時候都需要初始化處理的,在堆棧返回的時候會被自動收回。那麼構造函數和析構函數?其實是一樣的,在函數調用的時候,堆棧也會為這樣一個類准備大小合適的堆棧,然後調用構造函數對這樣的一片內存進行初始化處理,在函數return的時候,調用另外一個函數對可能涉及到的資源進行一次清理。這裡指的資源不是指內存空間,而是指廣義意義上的系統資源、比如說IO、socket、鎖、畫筆、對話框句柄等等。所以,通常而言,如果你在析構函數裡面沒有及時對資源進行分配,那麼就會造成資源的洩露。這一切只有等到程序結束的時候才會重新回到系統的手中,不過如果一個程序占有太多的資源,那麼勢必會對別的程序造成影響

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