C 為class設定專屬的new handler

2021-06-26 15:48:08 字數 1869 閱讀 4930

當operator new無法滿足某一記憶體分配需求時,它會丟擲乙個異常,以前它會返回乙個null指標。在operator new丟擲異常之前,它會呼叫客戶指定的錯誤處理函式,即new_handler。為了指定這個用以處理記憶體不足的函式,客戶必須呼叫set_new_handler,那是宣告於的乙個標準程式庫:   

namespace std
當operator new無法滿足記憶體申請時,它會不斷呼叫new_handler函式,就像下面的偽碼這樣:

void* operator new(std:size_t size) throw(std::bad_alloc)

while(true)

}

乙個設計良好的new_handler函式必須做以下事情:

1、讓更多的記憶體可被使用。這便造成operator new內的下一次記憶體分配動作可能成功。實現此策略的乙個做法是,程式一開始執行就分配一大塊記憶體,而後當new_handler第一次被呼叫,將它們釋還給程式使用。

2、安裝另乙個new_handler。如果目前這個new_handler無法取得更多更多可用的記憶體,或許它知道另外哪個new_handler有此能力。果真如此,目前這個new_handler就可以安裝另外那個new_handler以替換自己。下次當operator new呼叫new_handler,呼叫的將是最新安裝的那個。

3、卸除new_handler,也就是將null指標傳給set_new_handler。一旦沒有安裝任何new_handler,operator new會在記憶體分不足時丟擲異常。

以上是new_handler和set_new_handler相關知識,要實現class專屬之new_handler,只需令每乙個class提供自己的set_new_handler和operator new即可。假設你打算處理widget class記憶體分配失敗情況,你的class定義看起來像是這樣:

class widget;
widget的operator new做以下事情:

1、呼叫標準的set_new_hander,將widget的new_handler安裝為global new_handler。

2、呼叫global operator new,執行實際記憶體之分配。如果分配失敗,global operator new會呼叫widget的new_handler。如果global operator new最終無法分配足夠記憶體,會丟擲乙個異常。在此情況下widget的operator new必須恢復原本的global new_handler,然後再傳播異常。為確保原本的new_handler總能夠被重新安裝回去,widget將global operator new視為資源並用資源管理物件防止資源洩露。

3、如果global operator new能夠分配足夠乙個widget物件所用記憶體,widget的operator new將返回乙個指標,指向分配所得。widget的析構函式把widget的operator new被呼叫前的那個global operator new恢復回來。

下面是將global operator new作為資源進行管理的資源管理類:

class newhandlerholder

~newhandlerholder()

private:

std::new_handler handler;

};

這樣widget的operator new實現相當簡單:

void* widget::operator new(std::size_t size) throw(std::bad_alloc)

c 中的new 類建構函式 new

我們都知道在例項化乙個類時會使用這個類的 init 方法,但是在真實情況中類的例項化是分成兩個階段的,第一階段是使用該類的 new 方法例項化乙個物件,第二階段才是使用物件的 init 方法進行初始化。由於很多時候,第乙個階段被我們忽略了,所以看起來例項化類時只使用了 init 方法。既然在例項化類...

c 為函式設定動態引數

在宣告不確定形參的函式時,形參部分可以使用省略號 會告訴編譯器在函式呼叫時不檢查形參型別是否與實參型別相同,也不檢查引數個數 例如 void connectdata int i,上面的 編譯器只會檢查第乙個引數是否為整形,不對其他引數進行檢查 對於可變引數函式 首先需要引入cstdarg 標頭檔案 ...

c 中new的用法

c 中,new的用法很靈活,這裡進行了簡單的總結 x5 t d s v v9 n w j 1.new 分配這種型別的乙個大小的記憶體空間,並以括號中的值來初始化這個變數 u t,v u 2.new 分配這種型別的n個大小的記憶體空間,並用預設建構函式來初始化這些變數 8 a6 r i 6 g m l...