曾有人問過我構造函數的作用是幹什麼的?回答很簡單:“用來構造對象的”。於是滿腦子就形成了這樣
一種認識:一個對象只有在調用了構造函數以後,它所對應的內存塊纔有效。此思想存在了相當長的時間,
可以說直到寫這篇文章前夕。我們在寫構造函數時,如果構造函數形參和類成員變量同名,我們會用this
指針來加以區分。這從某種程度上已經暗示了調用構造函數時,類對象已經存在了。奈何思想頑固,對此
而不見。
下面從彙編的角度來說明,對象其實在調用構造函數之前就已經存在了。
using namespace std;
class A
{
public:
A( )
{
mem = 1;
};
virtual ~A( )
{
mem = 0;
};
int mem;
};
int main( )
{
A gg;
return 0;
}
24: A gg;
004038D8 lea ecx,[ebp-8]
004038DB call @ILT+720(A::A) (004012d5)
25: return 0;
004038E0 mov dword ptr [ebp-0Ch],0
004038E7 lea ecx,[ebp-8]
004038EA call @ILT+740(A::~A) (004012e9)
004038EF mov eax,dword ptr [ebp-0Ch]
26: }
首先對上面的彙編代碼做以下說明:
這是main函數中的一段代碼, 24 , 25 , 26分別對應着主函數中的A gg、return 0、 }
當調試停在004038D8指令上時,我們查看 &gg的值 爲 0x0012FF78,說明對象已經存在了。
也就是說構造函數只是類對象第一個調用的函數,而不是構造類對象內存塊的傢伙。
至於對象gg的析構是在 return 0;後調用的,注意看指令 004038EA 調用了類的析構函數,不過
掉了類的析構函數並不意味着對象對應的內存塊就無效了!對象gg對應的內存塊無效要等到 26以後。
這會在另一篇關於對析構函數的認識中說明。