Item 52 new/delete成對兒出現

來源:互聯網
上載者:User

● 通用概念
Widget *pw = new Widget;
其實分為兩步:
1> 調用operator new分配記憶體
2> 調用ctor初始化對象

如果第2步拋出異常,系統會自動調用
1> void operator delete(void *mem) throw();
2> void Widget::operator delete(void *mem, std::size_t size) throw();
二者之一來回收記憶體。

系統尋找和new對應的delete時是一一對應。如果對於一個placement new沒有給出placement delete,則無法回收記憶體。
所以,自訂new/delete時要保持一一對應:

class Widget {<br />public:<br />static void* operator new(std::size_t size, std::ostream& log) throw(std::bad_alloc);<br />static void operator delete(void *pMemory, std::ostream& log) throw();<br />...<br />};<br />Widget *pw = new (std::cerr) Widget;

 

此時若出現異常,系統會自動找到帶ostream的delete。

● STL中有一個placement new:
void* operator new(std::size_t, void *pMemory) throw();
該函數用於vector在內部給新對象尋找儲存位置。placement new因此而得名。placement是名詞“安置、尋找合適位置”的意思。
現在一般意義上,只要帶有多餘參數的new都叫placement new。系統在匹配placement new和placement delete時,也是靠比較那些多餘的參數而完成的。

● Item 33講了類在派生的時候,如果重名就會發生定義遮擋的問題:

class Base {<br />public:<br />static void* operator new(std::size_t size, std::ostream& log) throw(std::bad_alloc);<br />...<br />};<br />Base *pb = new Base; // 錯誤!預設的new被遮擋了<br />Base *pb = new (std::cerr) Base; // 正確<br />class Derived: public Base {<br />public:<br />// 這個厲害,把基類的也給擋了<br />static void* operator new(std::size_t size) throw(std::bad_alloc);<br />...<br />};<br />Derived *pd = new (std::clog) Derived; // 錯誤<br />Derived *pd = new Derived; // OK

 

先要瞭解C++預定義的new:

void* operator new(std::size_t) throw(std::bad_alloc); // normal new<br />void* operator new(std::size_t, void*) throw(); // placement new<br />void* operator new(std::size_t, const std::nothrow_t&) throw(); // no-throw new

這些都是你要在你的類裡重定義的。

簡單做法如下:

class StandardNewDeleteForms {<br />public:<br />// normal new/delete<br />static void* operator new(std::size_t size) throw(std::bad_alloc)<br />{ return ::operator new(size); }<br />static void operator delete(void *pMemory) throw()<br />{ ::operator delete(pMemory); }<br />// placement new/delete<br />static void* operator new(std::size_t size, void *ptr) throw()<br />{ return ::operator new(size, ptr); }<br />static void operator delete(void *pMemory, void *ptr) throw()<br />{ return ::operator delete(pMemory, ptr); }<br />// nothrow new/delete<br />static void* operator new(std::size_t size, const std::nothrow_t& nt) throw()<br />{ return ::operator new(size, nt); }<br />static void operator delete(void *pMemory, const std::nothrow_t&) throw()<br />{ ::operator delete(pMemory); }<br />};<br />// 誰想自訂new,就要從StandardNewDeleteForms裡派生<br />class Widget: public StandardNewDeleteForms {<br />public:<br />// 然後用using聲明一下標準的<br />using StandardNewDeleteForms::operator new;<br />using StandardNewDeleteForms::operator delete;<br />// 最後定義自己的<br />static void* operator new(std::size_t size, std::ostream& log) throw(std::bad_alloc);<br />static void operator delete(void *pMemory, std::ostream& log) throw();<br />...<br />};

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.