“new”是C++的一個關(guān)鍵字,同時也是操作符。關(guān)于new的話題非常多,因?yàn)樗_實(shí)比較復(fù)雜,也非常神秘,下面我將把我了解到的與new有關(guān)的內(nèi)容做一個總結(jié)。
new的過程
當(dāng)我們使用關(guān)鍵字new在堆上動態(tài)創(chuàng)建一個對象時,它實(shí)際上做了三件事:獲得一塊內(nèi)存空間、調(diào)用構(gòu)造函數(shù)、返回正確的指針。當(dāng)然,如果我們創(chuàng)建的是簡單類型的變量,那么第二步會被省略。假如我們定義了如下一個類A:
class A
{
int i;
public:
A(int _i) :i(_i*_i) {}
void Say() { printf("i=%dn", i); }
};
//調(diào)用new:
A* pa = new A(3);
那么上述動態(tài)創(chuàng)建一個對象的過程大致相當(dāng)于以下三句話(只是大致上):
A* pa = (A*)malloc(sizeof(A));
pa->A::A(3);
return pa;
雖然從效果上看,這三句話也得到了一個有效的指向堆上的A對象的指針pa,但區(qū)別在于,當(dāng)malloc失敗時,它不會調(diào)用分配內(nèi)存失敗處理程序new_handler,而使用new的話會的。因此我們還是要盡可能的使用new,除非有一些特殊的需求。
new的三種形態(tài)
到目前為止,本文所提到的new都是指的“new operator”或稱為“new expression”,但事實(shí)上在C++中一提到new,至少可能代表以下三種含義:new operator、operator new、placement new。
new operator就是我們平時所使用的new,其行為就是前面所說的三個步驟,我們不能更改它。但具體到某一步驟中的行為,如果它不滿足我們的具體要求 時,我們是有可能更改它的。三個步驟中最后一步只是簡單的做一個指針的類型轉(zhuǎn)換,沒什么可說的,并且在編譯出的代碼中也并不需要這種轉(zhuǎn)換,只是人為的認(rèn)識 罷了。但前兩步就有些內(nèi)容了。
new operator的第一步分配內(nèi)存實(shí)際上是通過調(diào)用operator new來完成的,這里的new實(shí)際上是像加減乘除一樣的操作符,因此也是可以重載的。operator new默認(rèn)情況下首先調(diào)用分配內(nèi)存的代碼,嘗試得到一段堆上的空間,如果成功就返回,如果失敗,則轉(zhuǎn)而去調(diào)用一個new_hander,然后繼續(xù)重復(fù)前面 過程。如果我們對這個過程不滿意,就可以重載operator new,來設(shè)置我們希望的行為。例如:
class A
{
public:
void* operator new(size_t size)
{
printf("operator new calledn");
return ::operator new(size);
}
};
A* a = new A();
相關(guān)推薦:計算機(jī)等級考試二級:C++學(xué)習(xí)重點(diǎn)分析試題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |