Effective C 條款52 第8章

2021-09-30 13:02:24 字數 1826 閱讀 8033

write placement delete if you write placement new

placement new 和 placement delete 並非在c++常見.回憶

條款16和

條款17,當寫乙個如下所示的 new 表示式:

widget* pw = new widget;
共有兩個函式被呼叫:乙個用以分配記憶體的 operator new,乙個widget的 default 建構函式.

假設其中第乙個函式呼叫成功,第二個函式卻丟擲異常.既然那樣,步驟一的記憶體分配所得必須取消並恢復舊觀,否則會造成記憶體洩露(memory leak).在這個時候,客戶並沒有能力歸還記憶體,因為如果widget建構函式丟擲異常,pw尚未被賦值,客戶手上也沒有指標指向該被歸還的記憶體.取消步驟一併恢復舊觀的責任因此落到c++執行期系統身上.

執行期系統會呼叫步驟一所呼叫的 operator new 的相應 operator delete 版本,前提當然是它必須知道哪乙個(因為可能有許多個)operator delete 該被呼叫.如果目前面對的是擁有正常簽名式(signature)的 new 和 delete,這並不是問題,因為正常的 operator new:

void* operator new(std::size_t) throw(std::bad_alloc);
對應於正常的 operator delete:

void operator delete(void* rawmemory) throw();

// global作用域中的正常簽名式

void operator delete(void* rawmemory, std::size_t size) thow();

// class作用域中典型的簽名式

因此,當只使用正常形式的 new 和 delete,執行期系統毫無問題可以找出那個"知道如何取消new所作所為並恢復舊觀"的 delete .然而當開始宣告非正常形式的 operator new,也就是帶有附加引數的 operator new,"究竟哪乙個delete伴隨這個new"的問題便浮現了.

如果 operator new 接受的引數除了一定會有的那個 size_t 之外還有其他,這便是所謂的placement new.因此,上述的 operator new 是個placement版本.眾多placement new 版本中特別有用的乙個是"接受乙個指標指向物件該被構造的地方",那樣的 operator new 類似這樣:

void* operator new(std::size_t, void* pmemory) throw(); // placement new
這個版本的 new 已被納入c++標準程式庫,只要#include 就可以取用它.這個 new 的用途之一是負責在vector的未使用空間上建立物件.實際上它正是這個函式的命名根據:乙個特定位置上的 new .

類似於 new 的placement版本,operator delete 如果接受額外引數,便稱為placement delete .

注意:

當寫乙個placement operator new,請確定也寫出相應的placement operator delete .如果沒有那樣做,程式可能會發生隱微而時斷時續的記憶體洩露.

當宣告placement new 和placement delete,請確定不要無意識(非故意)地遮掩了它們的正常版本.

Effective C 的52個條款列表

第一章 從c轉向c 條款1 盡量用const和inline而不用 define 條款2 盡量用而不用 條款3 盡量用new和delete而不用malloc和free 條款4 盡量使用c 風格的注釋 第二章 記憶體管理 條款5 對應的new和delete要採用相同的形式 條款6 析構函式裡對指標成員呼...

Effective C 的52個條款列表

第一章 從c轉向c 條款1 盡量用const和inline而不用 define 條款2 盡量用而不用 條款3 盡量用new和delete而不用malloc和free 條款4 盡量使用c 風格的注釋 第二章 記憶體管理 條款5 對應的new和delete要採用相同的形式 條款6 析構函式裡對指標成員呼...

Effective C 條款8 第2章

prevent exception from leving destructors.c 並不禁止析構函式吐出異常,但它不鼓勵這樣做.這是有原因的,考慮以下 class widget 假設這個可能吐出乙個異常 void dosomething v在這裡被自動銷毀當vector v被銷毀,它有責任銷毀其...