天天看點

類的operator new與operator delete的重載

為什麼有必要寫自己的operator new和operator delete?

答案通常是:為了效率。

預設版本的operator new是一種通用型的記憶體配置設定器,它必須可以配置設定任意大小的記憶體塊。同樣,operator delete也要可以釋放任意大小的記憶體塊。operator delete想弄清它要釋放的記憶體有多大,就必須知道當初operator new配置設定的記憶體有多大。有一種常用的方法可以讓operator new來告訴operator delete當初配置設定的記憶體大小是多少,就是在它所傳回的記憶體裡預先附帶一些額外資訊,用來指明被配置設定的記憶體塊的大小。

預設的operator new和operator delete具有非常好的通用性,它的這種靈活性也使得在某些特定的場合下,可以進一步改善它的性能。尤其在那些需要動态配置設定大量的但很小的對象的應用程式裡,情況更是如此。

記憶體池:記憶體池的作用主要也是為了效率。通過一次申請比較大的記憶體空間,來避免小空間記憶體的頻繁申請和釋放,每次需要為對象配置設定記憶體空間時,在已經申請的大空間内配置設定。空閑區被按照對象大小劃分為若幹塊,塊與塊之間通過連結清單組織起來。

參考代碼:

類的operator new與operator delete的重載

View Code

airplane類的說明:

airplane實際上是個句炳類(Handle class),通過指針airplanerep * rep指向一個具體的實作,airplane和airplanerep含有一樣的成員函數。句柄類實際上都做了些什麼:它隻是把所有的函數調用都轉移到了對應的主體類中,主體類真正完成工作。

operator new函數負責記憶體池連結清單的建立,記憶體池連結清單的每個塊大小和類airplane一樣,每次生成對象的時候配置設定一個塊給對象。

operator delete函數負責收回每個對象的記憶體塊,重新添加到記憶體池連結清單。

operator new和operator delete需要同時工作,那麼你寫了operator new,就也一定要寫operator delete。

一個聯合(使得rep和next域占用同樣的空間),一個常量(指定大記憶體塊的大小),一個靜态指針(跟蹤自由連結清單的表頭)。表頭指針聲明為靜态成員很重要,因為整個類隻有一個自由連結清單,而不是每個airplane對象都有。

注意:::operator new傳回的記憶體塊是從來沒有被airplane::operator delete釋放。記憶體洩漏和記憶體池有一個重要的不同之處:記憶體洩漏會無限地增長,而記憶體池的大小決不會超過客戶請求記憶體的最大值。

以上内容基本都來自《Effective C++》,稍作修改。

如果類定義了自己的成員new和delete,類的使用者可以通過使用全局作用域确定操作符,強制new和delete使用全局的庫函數。如:

Type *p = ::new Type;

::delete p;

如果new使用全局的operator new庫函數,那麼對應的delete也一定要用全局的operator delete庫函數。

一個記憶體配置設定器基類

CachedObj的功能:類似于記憶體池的功能。配置設定和管理已經配置設定但未構造對象的自由清單。operator new傳回自由清單中的一個元素,當自由清單為空時,operator new配置設定新的原始記憶體。operator delete在撤銷對象時将元素放回自由清單。

類的operator new與operator delete的重載

如何使用這個類:

類的operator new與operator delete的重載

    本文轉自阿凡盧部落格園部落格,原文連結:http://www.cnblogs.com/luxiaoxun/archive/2012/08/11/2633423.html,如需轉載請自行聯系原作者

繼續閱讀