【 聲明:著作權,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】
前面我們討論基本上都是C語言的內容,還沒有真正觸及到C++的相關知識。從這篇部落格之後,我們將會更多觸及類的內容。類的屬性很多,今天我們討論主要就是建構函式、解構函式。
(1)如果沒有建構函式、解構函式呢?
[cpp] view plaincopy
- class apple
- {
- public:
- void print() const {return;}
- };
雖然這個類沒有什麼意義,但是如果用sizeof計算一下大小的話,我們發現它還是佔了一個位元組。那麼如果有一個apple的變數呢?為了讓apple的變數有意義,我們嘗試做一個改變:
[cpp] view plaincopy
- 66: apple a;
- 67: a.print();
- 00401248 lea ecx,[ebp-4]
- 0040124B call @ILT+0(apple::print) (00401005)
- 68: return;
- 69: }
我們看到,堆棧分配了四個位元組空間給a,就是ebp下面的一個位元組。
(2) 解構函式什麼時候調用?
[cpp] view plaincopy
- class apple
- {
- public:
- apple() {printf("apple()!\n");}
- ~apple() {printf("~apple()!\n");}
- void print() const {return;}
- };
如果調用呢,我們可以做一個測試環境,如下所示:
[cpp] view plaincopy
- 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、鎖、畫筆、對話方塊控制代碼等等。所以,通 常而言,如果你在解構函式裡面沒有及時對資源進行分配,那麼就會造成資源的泄露。這一切只有等到程式結束的時候才會重新回到系統的手中,不過如果一個程式 佔有太多的資源,那麼勢必會對別的程式造成影響。