C++構造函數的幕後工作 .

 

快樂蝦

http://blog.csdn.net/lights_joy/

[email protected]

 

本文適用於

Xp sp3

Vs2008

 

歡迎轉載,但請保留作者信息

轉自:http://blog.csdn.net/lights_joy/article/details/4548382

 

多年前學習C++的時候就知道每個類都有一個默認的構造函數,但是爲什麼要有這樣的規則卻一直不求甚解,汗一個。剛好最近在重新學習C++的內存模型,看看它到底做了麼事?

寫一個簡單的類:

class CParentA

{

public:

     CParentA() {}

 

public:

     int parenta_a;

     int parenta_b;

 

public: 

     virtual void parenta_f1() {this->parenta_a = 0x10;}

     virtual void parenta_f2() {this->parenta_a = 0x20;}

 

public: 

     void parenta_f3() {this->parenta_a = 0x30;}

     void parenta_f4() {this->parenta_a = 0x40;}

};

看看構造函數的彙編代碼:

     CParentA() {}

00401330 55               push        ebp 

00401331 8B EC            mov         ebp,esp

00401333 51               push        ecx 

00401334 89 4D FC         mov         dword ptr [ebp-4],ecx

00401337 8B 45 FC         mov         eax,dword ptr [this]

0040133A C7 00 60 68 40 00 mov         dword ptr [eax],offset CParentA::`vftable' (406860h)

00401340 8B 45 FC         mov         eax,dword ptr [this]

00401343 8B E5            mov         esp,ebp

00401345 5D               pop         ebp 

00401346 C3               ret             

從這裏發現了兩行很有意思的代碼:

00401337 8B 45 FC         mov         eax,dword ptr [this]

0040133A C7 00 60 68 40 00 mov         dword ptr [eax],offset CParentA::`vftable' (406860h)

我們知道在有vtbl的情況下,this指向的前四個字節用來存放vtbl的指針原來在構造函數裏還有一個工作是要設置vtbl的指針。難怪C++非要在裏面插入一個構造函數。

刪除我們自己寫的構造函數,再構造一個CParentA的對象。

     CParentA pa;

0040111E 8D 4D F0         lea         ecx,[pa]   //尋址到pa 的內存位置

00401121 E8 39 FF FF FF   call        CParentA::CParentA (40105Fh)

還是要調用CParentA::CParentA,看看它做了什麼:

CParentA::CParentA:

004013D0 55               push        ebp 

004013D1 8B EC            mov         ebp,esp

004013D3 51               push        ecx 

004013D4 89 4D FC         mov         dword ptr [ebp-4],ecx

004013D7 8B 45 FC         mov         eax,dword ptr [this]

004013DA C7 00 60 68 40 00 mov         dword ptr [eax],offset CParentA::`vftable' (406860h)

004013E0 8B 45 FC         mov         eax,dword ptr [this]

004013E3 8B E5            mov         esp,ebp

004013E5 5D               pop         ebp 

004013E6 C3               ret             

比較兩個構造函數的彙編代碼可以發現,它們並沒有什麼不同。

那麼,假如一個類沒有虛函數,也就沒有vtbl,那麼它是不是就不需要生成構造函數了呢?試試將CParentA裏面的兩個虛函數去掉:

     CParentA pa;

 

可以發現,這行代碼果然不再生成對構造函數的調用!

 

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