(1)new operator
new的第一種形態是new operator,它是語言內建的,不能重載。new operator完成以下三件工作:
1. allocate memory for this object.
2. call constructor to init that memory.
3. return the pointer of this object.
例如:string *pStr = new string(“Memory Management”);
它實際完成以下三件事:
// 1. 爲string對象分配raw內存
void *memroy = operator new( sizeof(string) );
// 2. 調用構造函數初始化內存中的對象
call string::string() on memory
// 3. 獲得對象指針
string *pStr = static_cast<string *>(memory);
第1步申請內存,通過operator new完成;第2步在指定的內存上調用構造函數初始化對象,通過placement new完成。這便是new的另外兩種形態。
(2)operator new
operator new是普通操作符,和加減乘除操作符的地位一樣,可以重載。
默認情況下,operator new嘗試從堆上申請內存,如果成功則返回內存指針,如果失敗會調用new_handler,然後繼續重複前面過程,直到拋出異常(bad_alloc)爲止。
operator new函數原型:void * operator new(size_t size);
operator new可以重載,可以爲某個類單獨重載,也可以全局重載(將改變所有operator new的行爲方式)。如果重載了operator new,應該重載operator delete。
(3)placement new
(定位new)在已分配的原始內存中初始化一個對象。它與new的其他版本的不同之處在於,它不分配內存。相反,它接受指向已分配但未構造的內存的指針,並在該內存中初始化一個對象。placement new表達式能夠在特定的、預分配的內存地址上構造一個對象。
placement new是c++標準庫的一部分,使用時需包含<new>頭文件。
void *s = operator new( sizeof(A) ); A *p = (A*)s; new(p) A(2013); // p->A::A(2013); // processing code… p->~A();
如果顯示的調用placement new,也應該顯示的調用與之對應的placement delete:p->~A();。這份工作本來應該由編譯器自動完成:在使用new operator時,編譯器會自動生成調用placement new的代碼。所以,除非特別必要,不要直接使用placement new。只有當默認的new operator對內存的管理不能滿足需要,希望自己手動管理內存時,才考慮使用placement new。就像STL中的allocator一樣,它藉助placement new來實現更靈活有效的內存管理。
【學習資料】 《編寫高質量代碼 c++》 《thinking in c++》