剛看完了侯捷的《stl源碼剖析》,很不錯的一本書,打算對着vc的stl源碼來驗證一下。 而所有的C++對象第一步就是創建,我看了一下new中得代碼,大概做個記錄吧。理解的不深,純做記錄而已。
class CA
{
public:
CA(void);
~CA(void);
//void* operator new (size_t size);
};
CA::CA(void)
{
}
CA::~CA(void)
{
}
//void* CA::operator new (size_t size)
//{
// return malloc(size);
//
//}
這個類中我注掉的代碼就是重載了該類的new 運算符的實現, 去掉注銷的代碼是直接可以運行的。 測試用的main函數如下:
#include "A.h"
int main()
{
CA* a = new CA();
}
當編輯器在編譯這個CA* a = new CA();語句時, 會先去調用new函數,如過類中沒有自己定義的new函數,會去調用在<new>中得實現,該實現中是使用malloc來分配內存的,有一些異常處理的代碼。在調用完new分配好內存后,就調用 CA類的構造函數來對數據進行初始化。這個流程在《深入淺出C++對象模型》中有講的,剛翻了一下這本書。通過匯編代碼,也可以驗證這個流程
CA* a = new CA();
004114ED push 1 // 因為 CA為空,所以傳遞給new的size是1
004114EF call operator new (4111EAh) //調用new函數
004114F4 add esp,4
004114F7 mov dword ptr [ebp-0E0h],eax
004114FD mov dword ptr [ebp-4],0
00411504 cmp dword ptr [ebp-0E0h],0
0041150B je main+70h (411520h) //如果內存非配不成功,跳轉
0041150D mov ecx,dword ptr [ebp-0E0h]
00411513 call CA::CA (411014h) //內存分配好了, 然后調用 構造函數來 初始化對象
00411518 mov dword ptr [ebp-0F4h],eax // 將結果(指針值)放到一個內存里
0041151E jmp main+7Ah (41152Ah)
00411520 mov dword ptr [ebp-0F4h],0 //將 指針a 賦 0 值,表示分配未成功
0041152A mov eax,dword ptr [ebp-0F4h] //eax是 new CA(); 的返回值
這個流程比較簡單清晰,但是以前不知道的。 當時在看哪個《深入淺出C++對象模型》時,看了, 也忘了, 所以覺得有必要記錄一下。
有了new的基礎,以后再好好看看VC中stl的源碼的其他部分吧。 剛還捎帶看了一眼malloc的代碼,系統內部維護了一個列表
_CrtMemBlockHeader * pHead;
這個結構沒有看到定義,但是在運行時是可以看見的, 用vs看。