1. 程式人生 > >基於策略模式的定製new和delete

基於策略模式的定製new和delete

引言   在面向物件類的設計中,有時為了強化效能,特別是當構造大量小物件時,為了改善記憶體碎片,就需要自己實現物件的記憶體管理,以替換系統預設的分配和釋放行為,即全域性的new和delete。按照c++標準,在定製類專屬的new和delete時,為了減免客戶程式碼使用時的麻煩和問題,需要考慮同時定製簡單(normal new)定位(placement new)無異常(nothrow new)三種new情形,以及與之配對的三種delete情形,另外還有對應的陣列new[]和delete[]各三種情形。在介面設計上,每種情形都是operator new和operator delete的過載版本;在記憶體管理上,具體的物件空間分配和釋放是靈活的,因此這一部分可實現為策略模式,通過改變替換不同的記憶體管理策略,即可輕易獲得不同的記憶體分配和釋放行為,而類的程式碼則無須改變。為了方便定製類的new和delete,可以從一個介面基類模板繼承而自動獲得這種特性。這個基類模板實現了單個物件的new、delete和物件陣列的new、delete,而模板引數正是記憶體管理策略類,它的設計約束如下:
   1)必須存在static成員方法malloc
free,其引數和返回值與C庫的malloc和free一致。
   2)malloc只分配空間,若分配成功則不必初始化,否則失敗返回NULL,不能丟擲異常,因為normal new的語義為對於分配失敗則丟擲std::bad_alloc異常,而nothrow new則返回NULL,如此兩種方式兼備,有利於客戶程式碼的按需靈活檢測;free只釋放或歸還空間。
   3)malloc和free的內部實現是靈活的,由應用開發者定製。

元件   這裡實現了new_delete_policy_baseobject_pool_impl兩個基礎元件,程式碼如下,前者是支援記憶體管理策略的定製new和delete介面基類模板,從該類繼承的子類其物件的構造和析構就被定製了;後者是支援記憶體管理策略的非侵入式物件池類模板,可直接用於構造某類的物件,包括內建的基本資料型別,而該類不必從new_delete_policy_base繼承。  1
template<class Alloc> 2class new_delete_policy_base
 3{
 4public:
 5    staticvoid*operatornew(size_t size) throw (std::bad_alloc)
 6    {  
 7        void* ptr = Alloc::malloc(size);
 8        if(NULL==ptr) {
 9            throw std::bad_alloc();
10        }
11        return ptr;
12    }
13
14    staticvoid*operatornew(size_t size,void* ptr) throw()
15    return ptr; }16
17    staticvoid*operatornew(size_t size,const std::nothrow_t&throw()
18    return Alloc::malloc(size); }19
20    staticvoidoperator delete(void* ptr) throw()
21    {  Alloc::free(ptr); }22
23    staticvoidoperator delete(void* ptr, const std::nothrow_t&throw()
24    {  Alloc::free(ptr); }25
26    staticvoidoperator delete(void*void*throw()
27    { }28
29    staticvoid*operatornew[](size_t size) throw(std::bad_alloc)
30    returnoperatornew (size); }31    
32    staticvoid*operatornew[](size_t size,void* ptr) throw()
33    return ptr; }34
35    staticvoid*operatornew[](size_t size, const std::nothrow_t&throw()
36    returnoperatornew (size, std::nothrow); }37
38    staticvoidoperator delete[](void* ptr) throw()
39    {  operator delete (ptr); }40
41    staticvoidoperator delete[](void* ptr, const std::nothrow_t&throw()
42    operator delete (ptr); }43
44    staticvoidoperator delete[](void*void*throw()
45    { }46}
;
47
48template<class Alloc>49class object_pool_impl
50{
51public:
52    template<typename T>53    static T* construct() 
54    {
55        T*const p = static_cast<T*>(Alloc::malloc(sizeof(T)));
56        trynew (p) T(); }57        catch(){ Alloc::free(p); throw; }58        return p;
59    }
60
61    template<typename T>62    staticvoid destroy(T*const ptr)
63    {
64        ptr->~T();
65        Alloc::free(ptr);
66    }
67}
;
應用   下面程式碼中的mem_pool是一種基於自由列表機制實現的記憶體池,quick_object從new_delete_policy_base<mem_pool>繼承,用於演示定製new和delete的行為,_THROW_EXCEPTION巨集用於遮蔽程式碼,測試當物件空間分配成功但建構函式丟擲異常時,對應的operator delete是否得到呼叫,而保證釋放記憶體空間,normal_object是空類,它不從new_delete_policy_base<mem_pool>繼承,用於演示物件池構造和銷燬物件的行為。
 1class quick_object : public new_delete_policy_base<mem_pool> 2{
 3public:
 4    quick_object() 
 5    {
 6#ifdef _THROW_EXCEPTION
 7        throw0;
 8#endif 9        cout <<"quick_object()"<< endl;    
10    }
11    ~quick_object()
12    {
13        cout <<"~quick_object()"<< endl;
14    }
15}
;
16
17class normal_object
18{
19public:
20    normal_object() 
21    {
22        cout <<"normal_object()"<< endl;        
23    }
24    ~normal_object()
25    {
26        cout <<"~normal_object()"<< endl;
27    }
28}
;
29
30

相關推薦

基於策略模式定製newdelete

引言   在面向物件類的設計中,有時為了強化效能,特別是當構造大量小物件時,為了改善記憶體碎片,就需要自己實現物件的記憶體管理,以替換系統預設的分配和釋放行為,即全域性的new和delete。按照c++標準,在定製類專屬的new和delete時,為了減免客戶程式碼使用時的麻煩和問題,需要考慮同時定

effective C++筆記--定製newdelete(二)

文章目錄 編寫new和delete時需固守常規 寫了placement new也要寫 placement delete 編寫new和delete時需固守常規 . 在編寫自己的operator new和operator delete時,需要

effective C++筆記--定製newdelete(一)

文章目錄 瞭解new-handler的行為 瞭解new和delete的合理替換時機 . C++允許手動的管理記憶體,這是雙刃劍,你可以使程式更有效率,也可能面臨維護程式帶來的麻煩,所以瞭解C++記憶體管理的例程很是重要,其中的兩個主角是分配例

《Effective C++》定製newdelete:條款49-條款52

條款49:瞭解new-handler的行為 當operator new無法分配出記憶體會丟擲異常std::bad_alloc 丟擲異常前會反覆呼叫使用者自定義的new-handler函式直至成功分配記憶體 // 自定義new_handler函式 void outOfMem() { c

Effective C++ 筆記(8.定製newdelete)

     多執行緒環境下的記憶體管理,遭受單執行緒系統不曾有過發挑戰。由於heap是一個可被改動的全域性性資源,因此多執行緒系統充斥著發狂訪問這一類資源的race conditions(競速狀態)出現機會。    如果沒有適當的同步控制(synchronization),一旦

newdelete

沒有 names ffi .com 傳遞 ptr 編譯器 html htm 轉載請註明原文出處,http://www.cnblogs.com/flyingcloude/p/6992498.html #include <iostream>using nam

2.16 C++類與newdelete操作符

運行 out 可能 clas cout std 存儲 分配 程序 參考: http://www.weixueyuan.net/view/6347.html 總結:    當我們需要為類對象動態分配存儲空間時,我們應該使用C++語言提供的new與new[]操作符,而不要使用C

c++中的newdelete

程序設計 wan https 解決 運算符 AI 指向 log cnblogs 對於計算機程序設計而言,變量和對象在內存中的分配都是編譯器在編譯程序時安排好的,這帶來了極大的不便,如數組必須大開小用,指針必須指向一個已經存在的變量或對象。對於不能確定需要占用多少內存的情況,

動態內存管理——newdelete底層探索

new delete 動態內存管理 原文鏈接:https://blog.csdn.net/qq_38646470/article/details/79824464專欄鏈接:https://blog.csdn.net/column/details/20026.html[TOC]#1.new/dele

newdelete的三種形式詳解

分別是 額外 ID 調用 pre else class code alloc 一、new操作符、delete操作符 class String { public: String(const char *str="") { if

effective c++ 條款16:成對使用newdelete時要采用相同形式

最好 class 你在 pan TE fec IV line PE 記住: 如果你在new表達式中使用[ ],必須在相應的delete表達式中也是用[ ]。如果你在new時不使用[ ],一定不要在delete時使用[ ]。 string* stringPtr1 = n

C++基礎 newdelete

style 析構函數 對比 pan delete 基本數據類型 交叉 del 報錯 1.new delete 的使用 (1)基本數據類型 int *p = new int(10); delete p; int *p = (int *)malloc(sizeof(int))

effective c++條款16:成對使用newdelete時要採取相同形式

下面的程式碼會產生什麼樣的後果? #include <iostream> using namespace std; int main(void) { std::string *StringArray = new std::string[30]; delete StringAr

C++中newdelete之後發生了什麼

眾所周知,如果我們使用new向系統申請了記憶體,我們應該使用指標指向這一塊記憶體,俾能我們使用結束後,通過delete該指標釋放此記憶體資源。 如果理解只達到這種程度,在記憶體管理稍微複雜一點時便一定會束手無策。總有一些事情比其他事情更基本一點,現在我來談談當我們new和delete之後

C++中newdelete的用法

new和delete運算子用於動態分配和撤銷記憶體的運算子 new用法:           1.     開闢單變數地址空間  

控制記憶體分配----過載newdelete & 定位new表示式

文章來源C++  Primer 第五版 過載new和delete 注: 1、瞭解operate new和operate delete各自的功能;2、解構函式只是銷燬物件,而不會釋放掉記憶體,這也就解釋了delete表示式為什麼是執行了兩步。 關於noexcept有關知識

C++ Memory System Part1: newdelete

part 也有 其中 oid 事情 oca ddr temp 高級工程師 在深入探索自定義內存系統之前,我們需要了解一些基礎的背景知識,這些知識點是我們接下裏自定義內存系統的基礎。所以第一部分,讓我們來一起深入了解一下C++的new和delete家族,這其中有很多令人吃驚的

C++ new delete運算子

目錄   動態記憶體 內建的資料型別的分配 陣列的動態記憶體分配 物件的動態記憶體分配 動態記憶體 C++ 程式中的動態記憶體分為兩個部分: 棧:在函式內部宣告的所有變數都將佔用棧記憶體。 堆:這是程式中未使用的記憶體,在程式執行時可用於動態

【C++】C++ newdelete操作符

C++新增了兩個關鍵字,new 和 delete:new 用來動態分配記憶體,delete 用來釋放記憶體。 用 new 和 delete 分配記憶體更加簡單: int *p = new int; //分配1個int型的記憶體空間 delete p; //釋放記憶體 ne

成對使用newdelete時要採取相同形式

delete 基本型別直接呼叫free。 複雜型別先呼叫解構函式,再呼叫operator delete. delet[] 基本型別直接呼叫operator delete. 複雜型別先取出指標前面的四個位元組的數字,決定呼叫幾次解構函式,再呼叫operator delete.在這裡需要注意的是如果在這裡呼叫de