對C++構造函數的認識

       學C++已經有一段時間了,但是對一些東西的理解任然停留在書本上,沒有更深刻的認識。比如如題。
      曾有人問過我構造函數的作用是幹什麼的?回答很簡單:“用來構造對象的”。於是滿腦子就形成了這樣
一種認識:一個對象只有在調用了構造函數以後,它所對應的內存塊纔有效。此思想存在了相當長的時間,
可以說直到寫這篇文章前夕。我們在寫構造函數時,如果構造函數形參和類成員變量同名,我們會用this
指針來加以區分。這從某種程度上已經暗示了調用構造函數時,類對象已經存在了。奈何思想頑固,對此
而不見。
    下面從彙編的角度來說明,對象其實在調用構造函數之前就已經存在了。
   
#include<iostream>
using namespace std;

class A
{
public:
    A( )
    
{
        mem 
= 1;
    }
;
    
virtual ~A( )
    
{
        mem 
= 0;
    }
;
    
int mem;
}
;

int main( )
{
    A gg;
    
return 0;
}
在主函數 A    gg;插入斷點,運行,Alt + 8  ,查看底層的彙編代碼。
   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以後。
這會在另一篇關於對析構函數的認識中說明。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章