【 聲明:版權所有,歡迎轉載,請勿用於商業用途。 聯系信箱: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、鎖、畫筆、對話框句柄等等。所以,通常而言,如果你在析構函數裡面沒有及時對資源進行分配,那麼就會造成資源的洩露。這一切只有等到程序結束的時候才會重新回到系統的手中,不過如果一個程序占有太多的資源,那麼勢必會對別的程序造成影響