c 中new的知識點

2022-02-02 08:20:10 字數 2169 閱讀 7453

在練習記憶體池時,發現需要過載new,可是這個過載只是過載了operator new,那麼還有哪幾種new呢,下面來記錄一下

首先記錄乙個點,在類中過載operator new,預設就是靜態成員函式,所以不能生命為虛函式,不能呼叫非靜態成員變數

下面正文,c++有三種new

說的通俗點。1、new運算子(new operator)大哥,我們在**中直接使用的就是它。它做2件事:呼叫後兩種new申請記憶體和初始化物件。2、operator new,是乙個函式,所以也是三種new唯一乙個可以過載的。它類似c語言中的malloc,用於分配記憶體。3、placement new,用於初始化物件(如果有的話,就是它呼叫建構函式)

1.operator new

void *operator

new(size_t);

void *operator

new(size_t);

void *operator

delete(void*);

void *operator delete(void*);

入參型別必須為size_t,返回型別必須為void *.可以過載為多個引數版本如下

void *operator new(size_t t1,size_t t2);

這樣如果呼叫未 void *p= new(10) int;時 t2的大小就為10.而t1的大小一直是固定的(可能根據系統不同而變化)

這個是我們唯一可以過載的new,不僅可以在類內過載,全域性operator new也可以被過載。如果全域性operator new被過載的話,那麼除了類內的過載會覆蓋全域性的過載,任何地方呼叫new 都會呼叫到這個全域性過載的函式裡

2.new operator

當你寫string *ps = new string(「hands up!」)時,你所使用的new是所謂的new operator,它其實幹了兩件事:

一、分配足夠的記憶體(實際大小是大於所建立的物件大小,因為有管理的資料),即operator new。

二、呼叫物件建構函式,new operator永遠幹這兩件事。上面的那段**大約反映以下的行為

void *mem = operator new(sizeof(string));

call string::string(「hands up!」) on *mem;//只能由編譯器完成,使用者是不允許這樣操作的,也就是說如果你想建立乙個堆物件就必須用new操作符,不能直接像上面一樣呼叫建構函式來初始化堆物件。

也就是說operator new僅僅分配記憶體(就像malloc一樣),我們能夠做的僅僅是過載operator new,為自己的類建立乙個定製的記憶體管理方案,

這也讓我有點明白為什麼在過載operator new的時候並沒有寫呼叫建構函式的**,但它確實被呼叫了,原來都是new operator搞的鬼。

編譯器看到類型別的new或者delete表示式的時候,首先檢視該類是否是有operator new或者operator delete成員,如果類定義了自己的new和delete函式,則使用這些函式為物件分配和釋放記憶體,否則呼叫標準庫版本。如果你想定製自己獨有的記憶體分配過程,你應該過載全域性的operator new函式,然後使用new操作符,new操作符會呼叫你定製的operator new。當然你可以顯示的呼叫:: operator new和:: operator delete強制使用全域性的庫函式

3.定位new表示式

即placement new,定位new表示式在已分配的與原始記憶體中初始化乙個物件,他與new的其他版本不同,它不分配記憶體。相反,它接受指向已分配好但未構造的記憶體指標,並在該記憶體中初始化乙個物件。實際上,定位new表示式使我們在特定的、預分配的記憶體位址構造乙個物件。它可以定義類的任何建構函式。

new

(place_address) type

new(place_address) type(initializer_list)

舉個例子,

我們也可以直接來使用它,你手上有一塊記憶體p。int *p2 = new (p) int(100); 這樣你就用placement new把一塊記憶體初始化為int,並給它個初值100。其實這裡,p所指向的記憶體可以是堆也可以是棧。如果是棧記憶體被這樣new,不需要delete,且可以反覆的new。這有什麼用, 你可以把動態分配記憶體的請求限制在一塊區域內,這就有點像作業系統給引用程式分配記憶體,這一塊給你隨便用, 妨礙不到其他的記憶體。算是一種安全策略吧。

c 中的知識點

1.類和結構的區別 1.從儲存上,類儲存在堆上的引用,結構是儲存在棧上的值型別 2.從關鍵字上,類使用class,結構使用struct 3.繼承上,類可以繼承,結構不可以繼承 4.類是引用型別,結構是值型別 2ref和out區別 ref無論是按值傳遞還是按照引用傳遞,任何變數都要初始化 out變數不...

C基礎中的知識點

二進位制與八進位制,十六進製制的轉換 二進位制的3位相當於8進製的1位 二進位制的4位相當於16進製制的1位 getchar 從鍵盤獲取乙個字元,有返回值,返回獲取的那個字元,沒獲取字元將一直等待 getchar 函式可用作吸收殘留的回車鍵,放在scanf後面 字元加單引號表示ascii碼值 字元常...

C 中的引用(重要知識點)

引用即別名 對變數取另外的名稱,相當於是取了乙個錯號。引用變數與其所引用的變數的位址其實是同乙個 c 用引用來取代指標 宣告引用變數 資料型別 變數名 變數 資料型別 和 變數 的型別必須完全一致 1.引用必須初始化 引用一經定義必須初始化 int z 錯誤的 include using names...