10.如果寫了operator new,就要同時寫operator delete。
為什麼要寫自己的operator new和delete,首先這不叫重載,這叫隱藏。 new只是用來申請空間,而構造函數是在申請的空間的基礎上繼續初始化。
為了效率。缺省的operator new 進行內存分配是並不僅僅分配一塊所需大小的內存,因為delete釋放內存時要知道指針所指向內容的大小,所以,new時會有一個塊來儲存內存塊的大小,而delete時,會根據這個大小來判斷刪除內存大小。所以當一個類本身很小的時候,這樣做,既浪費時間於內存大小的判斷,也浪費空間於內存大小的保存。對於某些類較小,且需要一定數量的這些小對象來儲存數據時,最好能寫一個operator new 來節約空間與時間。
而由於自己的Operator new申請的內存塊中沒有保存內存塊的大小,導致使用缺省的delete時,會導致不可預測的後果。所以若寫了operator new ,就必須同時寫operator delete。
一般解決方法是 申請一大塊內存,作為內存池,將其分為若干塊,每塊大小正好為儲存對象的大小。當前沒有被使用時。
嘗試將這種固定大小內存的分配器封裝起來。
//內存池的實現。 class Pool{ public: Pool (size_t n,int size); void* alloc(size_t n);//為一個對象分配足夠的內存 void free(void* p,size_t n);//將p指定的內存返回到內存池。 ~Pool();//釋放內存池中的全部資源 private: void* block; const int BLOCK_SIZE;//池內存放塊的數量 void* list; }; Pool::Pool(size_t n,int size):BLOCK_SIZE(size){ block = ::operator new(n*size); int i; for(i = 0;i
這是一個內存池的實現,結果感覺雖然實現了內存池的基本功能,但寫的不好看。。。譬如一些問題沒有解決,如果要求內存大於池的最大容量的處理,以及釋放池內元素時,如果重復釋放需要進行一些判斷此塊內存釋放已釋放。
忽略上面代碼,簡單分析一下內存池的基本功能:alloc 為對象申請空間的請求提供內存,而free釋放對象現在所在的內存。
這裡說的寫了 operator new 就要寫對應的operator delete,因為你在自己寫的new中一定會定義一些其他的操作,使的數據的組織結構不是一個簡單的new就實現的,可能有多塊動態地址,或者可能像內存池中並沒有實際的去申請新的空間,所以一定要根據自己寫的new中的操作,設計對應的delete操作。