很多新手對c++關鍵字new可能不是很了解吧,今天我一起來學習一下。
「new」是c++的乙個關鍵字,同時也是操作符。關於new的話題非常多,因為它確實比較複雜,也非常神秘,下面我將把我了解到的與new有關的內容做乙個總結。
new的過程
當我們使用關鍵字new在堆上動態建立乙個物件時,它實際上做了三件事:獲得一塊記憶體空間、呼叫建構函式、返回正確的指標。當然,如果我們建立的是簡單型別的變數,那麼第二步會被省略。假如我們定義了如下乙個類a:
class a
void say()
};//呼叫new:
a* pa = new a(3);
那麼上述動態建立乙個物件的過程大致相當於以下三句話(只是大致上):
a* pa = (a*)malloc(sizeof(a));
pa->a::a(3);
return pa;
雖然從效果上看,這三句話也得到了乙個有效的指向堆上的a物件的指標pa,但區別在於,當malloc失敗時,它不會呼叫分配記憶體失敗處理程式new_handler,而使用new的話會的。因此我們還是要盡可能的使用new,除非有一些特殊的需求。
new的三種形態
到目前為止,本文所提到的new都是指的「new operator」或稱為「new expression」,但事實上在c++中一提到new,至少可能代表以下三種含義:new operator、operator new、placement new。
new operator就是我們平時所使用的new,其行為就是前面所說的三個步驟,我們不能更改它。但具體到某一步驟中的行為,如果它不滿足我們的具體要求時,我們是有可能更改它的。三個步驟中最後一步只是簡單的做乙個指標的型別轉換,沒什麼可說的,並且在編譯出的**中也並不需要這種轉換,只是人為的認識罷了。但前兩步就有些內容了。
new operator的第一步分配記憶體實際上是通過呼叫operator new來完成的,這裡的new實際上是像加減乘除一樣的操作符,因此也是可以過載的。operator new預設情況下首先呼叫分配記憶體的**,嘗試得到一段堆上的空間,如果成功就返回,如果失敗,則轉而去呼叫乙個new_hander,然後繼續重複前面過程。如果我們對這個過程不滿意,就可以過載operator new,來設定我們希望的行為。例如:
class a
};a* a = new a();
這裡通過::operator new呼叫了原有的全域性的new,實現了在分配記憶體之前輸出一句話。全域性的operator new也是可以過載的,但這樣一來就不能再遞迴的使用new來分配記憶體,而只能使用malloc了:
void* operator new(size_t size)
相應的,delete也有delete operator和operator delete之分,後者也是可以過載的。並且,如果過載了operator new,就應該也相應的過載operator delete,這是良好的程式設計習慣。
new的第三種形態——placement new是用來實現定位構造的,因此可以實現new operator三步操作中的第二步,也就是在取得了一塊可以容納指定型別物件的記憶體後,在這塊記憶體上構造乙個物件,這有點類似於前面**中的「p->a::a(3);」這句話,但這並不是乙個標準的寫法,正確的寫法是使用placement new:
new關鍵字 this關鍵字 base關鍵字
使用new,所做的三件事 1.類是引用物件,引用物件是在堆中開闢空間 在堆中開闢空間 2.在開闢的堆空間中建立物件 3.呼叫物件的構建函式 4.隱藏父類成員 子類的成員可以與隱藏從父類繼承的成員,類似於重寫。public new void sayhello this關鍵字的使用 1.代表當前類的物件...
手寫 new 關鍵字
function mynew func,args 新物件原型指向建構函式原型物件 obj.proto func.prototype 將建構函式的this指向新物件 let result func.obj,args 根據返回值判斷 return result instanceof object res...
new 關鍵字相關
初始化動態分配的陣列 動態分配陣列時,如果陣列元素具有類型別,將使用該類的預設建構函式 c primer第 2.3.4 節 實現初始化 如果陣列元素是內建型別,則無初始化 string psa new string 10 array of 10 empty strings int pia new i...