effective c 讀書筆記 八

2021-08-08 23:17:24 字數 2726 閱讀 2952

主角是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替換...