主角是operator new 和operator delete,配角是new-handler,當operator new無法滿足客戶的記憶體需求時所呼叫的函式。
多執行緒環境下的記憶體管理,比單執行緒複雜的多。由於heap是乙個可悲改動的全域性性資源,因此多執行緒系統充斥這發狂訪問這一類資源的race conditions出現機會。
namespace
std
乙個設計良好的new-handler函式必須做以下事情:
1.讓更多記憶體可被使用。實現此策略的做法是,程式一開始執行就分配一大塊記憶體,而後當new-handler第一次呼叫時,將它們釋放還給程式使用。
2.安裝另乙個new-handler。就是說目前這個new-handler無法取得更多的記憶體,如果另外乙個new-handler有這個能力,應該呼叫另外乙個new-handler來完成這個任務。實現方法:令new-handler修改會影響new-handler行為的static資料,namespace資料和global資料。
3.卸除new-handler。將null指標傳給set_new_handler。一旦沒有安裝任何new-handler,operator new會在記憶體分配不成功時丟擲異常
4.丟擲bad_alloc的異常。這樣的異常不會被operator new 捕捉,因此會被傳播到記憶體索求處。
5.不返回。通常呼叫abort或exit。
替換編譯器提供的operator new或operator delete的理由:
1. 用來檢測運用上的錯誤。
2. 為了強化效能。
3. 為了收集使用上的統計資料。
4. 為了增加分配和歸還的速度。
5. 為了降低預設記憶體管理器帶來的空間額外開銷
6. 為了彌補預設分配器中的非最佳齊位
7. 為了將相關物件成簇集中。
8. 為了獲得非傳統行為
實現一致性operator new必須返回正確的值,記憶體不足時必得呼叫new-handling函式,必須有對付零記憶體需求的準備,還需避免不慎遮蓋正常形式的new–雖然這比較偏近class的介面要求而非實現要求。
void* operator
new(std::size_t size) throw(std::bad_alloc)
while(true)
}
繼承operator new成員函式的derived class會導致怪異的問題。
class base;
class derived : public base
derived *p = new derived;
void* base::operator
new(std::size_t size) throw(std::bad_alloc)
如果決定寫個operator new,唯一需要做的就是分配一塊未加工的記憶體,因為無法對array內迄今尚未存在的元素物件做任何事情。
operator delete,需要保證刪除null指標永遠安全。
void
operator
delete(void *rawmemory) throw()
class base;
void base::operator
delete(void* rawmemory, std::size_t size) throw()
//歸還rawmemory所指記憶體
return;
}
如果乙個帶額外引數的operator new沒有帶相同額外引數的對應版operator delete,那麼當new的記憶體分配動作需要取消並恢復舊觀時就沒有任何operator delete會被呼叫。
class widget;
widget* pw = new(std::cerr) widget; //丟擲異常時,不會導致記憶體洩漏,可以恢復如初
如果你在class內宣告任何operator news,它會遮蔽上述的標準形式,實現所有自定義的new和標準的new都可以用的簡單做法就是,建立乙個base class,內含所有正常形式的new和delete
class standardnewdeleteforms
static
void
operator
delete(void* memory) throw()
static
void* operator
new(std::size_t size, void* ptr) throw()
static
void
operator
delete(void* memory, void* ptr) throw()
static
void* operator
new(std::size_t size, const
std::nothrow_t& nt) throw()
static
void
operator
delete(void* memory,const
std::nothrow_t&) throw()
};
然後可以通過using宣告式來獲取標準形式
class widget: public standardnewdeleteforms;
《effective C 》讀書筆記
1,c 關鍵字explicit c 中,乙個引數的 建構函式 或者除了第乙個引數外其餘引數都有預設值的多參建構函式 承擔了兩個角色。1 是個 構造器,2 是個預設且隱含的型別轉換操作符 所以,有時候在我們寫下如 aaa 這樣的 且恰好 的型別正好是aaa單引數構造器的引數型別,這時候 編譯器就自動呼...
Effective C 讀書筆記
一 讓自己習慣c 1 條款01 視c 為聯邦語言 c 的組成可分為四部分 1.c c 仍然以c語言為基礎。區塊 語句 預處理 內建資料型別 陣列 指標等都來自c。2.object oriented c c with classes所訴說的 classes 包括構造和析構 封裝 繼承 多型 virtu...
讀書筆記 Effective C
部分條款過於深奧,部分條款已了然於心,僅記錄當下所識所學 對於常量巨集定義,最好用const代替 define 對於函式巨集定義,最好用inline代替 define include ifdef ifndef仍被需要 內建物件記得手動初始化 使用成員初始列替換賦值操作 以local static替換...