• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-159  評論-223  文章-30  trackbacks-0
            引言
               在面向對象類的設計中,有時為了強化效能,特別是當構造大量小對象時,為了改善內存碎片,就需要自己實現對象的內存管理,以替換系統缺省的分配和釋放行為,即全局的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成員方法mallocfree,其參數和返回值與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繼承。
             1template<class Alloc>
             2class new_delete_policy_base
             3{
             4public:
             5    static void* operator new(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    static void* operator new(size_t size,void* ptr) throw()
            15    return ptr; }
            16
            17    static void* operator new(size_t size,const std::nothrow_t&throw()
            18    return Alloc::malloc(size); }
            19
            20    static void operator delete(void* ptr) throw()
            21    {  Alloc::free(ptr); }
            22
            23    static void operator delete(void* ptr, const std::nothrow_t&throw()
            24    {  Alloc::free(ptr); }
            25
            26    static void operator delete(void*void*throw()
            27    { }
            28
            29    static void* operator new[](size_t size) throw(std::bad_alloc)
            30    return operator new (size); }
            31    
            32    static void* operator new[](size_t size,void* ptr) throw()
            33    return ptr; }
            34
            35    static void* operator new[](size_t size, const std::nothrow_t&throw()
            36    return operator new (size, std::nothrow); }
            37
            38    static void operator delete[](void* ptr) throw()
            39    {  operator delete (ptr); }
            40
            41    static void operator delete[](void* ptr, const std::nothrow_t&throw()
            42    operator delete (ptr); }
            43
            44    static void operator 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        try new (p) T(); }
            57        catch(){ Alloc::free(p); throw; }
            58        return p;
            59    }

            60
            61    template<typename T>
            62    static void 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        throw 0;
             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/**
            31 *    the following code,if quick_object's construct function throw exception,then result in
            32 *    c/c++ Run-time system call operator delete correspond to operator new automaticlly.
            33 */

            34static void unit_test_new_delete_policy()
            35{    
            36    quick_object* obj = NULL;
            37
            38    try {
            39        obj = new quick_object; //call simple new
            40        delete obj;             //call simple delete
            41    }
            catch(){
            42        //call simple delete
            43    }

            44
            45    try {
            46        obj = new (std::nothrow) quick_object; //call nothrow new
            47        delete obj; //call simple delete
            48    }
            catch(){
            49        // call nothrow delete
            50    }

            51
            52    try {
            53        char ptr[sizeof(quick_object)];
            54        obj = new (ptr) quick_object; //call placement new
            55    }
            catch(){
            56        //call placement delete
            57    }

            58    
            59    try{
            60        obj = new quick_object[10]; //call simple new[]
            61        delete []obj;        //call simple delete[]
            62    }
            catch(){
            63        //call simple delete[]
            64    }

            65
            66    try {
            67        obj = new (std::nothrow) quick_object[10]; //call nothrow new[]
            68        delete []obj; //call simple delete[]
            69    }
            catch(){
            70        //call nothrow delete[]
            71    }

            72
            73    try {
            74        char ptr[sizeof(quick_object[10])];
            75        obj = new (ptr) quick_object[10];    //call placement new[]
            76    }
            catch ({
            77        //call placement delete[]
            78    }

            79}

            80
            81/**
            82 *    class quick_object is inherited from class new_delete_policy_base<mem_pool> that has implement 
            83 *    operator new and delete,so that call placement new in template member construct of class obj_pool.
            84 */

            85static void unit_test_obj_pool()
            86{
            87    typedef object_pool_impl<mem_pool> obj_pool;
            88
            89    try{
            90        quick_object* obj = obj_pool::construct<quick_object>();
            91        obj_pool::destroy(obj);
            92    }
            catch ({
            93
            94    }

            95    //class normal_object's construct function do not throw exception.
            96    normal_object* obj = obj_pool::construct<normal_object>();
            97    obj_pool::destroy(obj);
            98}
            posted on 2012-09-27 17:37 春秋十二月 閱讀(2080) 評論(2)  編輯 收藏 引用 所屬分類: C/C++

            評論:
            # re: 一種簡單的跨平臺信號量[未登錄] 2012-10-07 07:52 | Chipset
            很好的總結  回復  更多評論
              
            # re: 一種簡單的跨平臺信號量 2013-02-18 14:15 | GFree_Wind
            呵呵,今天剛看到你給我博客的評論。

            我來回訪了呵。
            我覺得跨平臺的信號量,像你這樣利用宏進行條件編譯可以。
            但是也可以自己來實現一個跨平臺的信號量。

              回復  更多評論
              
            一级女性全黄久久生活片免费| 狠狠干狠狠久久| 久久91精品综合国产首页| 成人国内精品久久久久影院| 久久久久人妻精品一区| 久久亚洲欧美国产精品| 久久棈精品久久久久久噜噜| 久久国产亚洲高清观看| 狠狠色丁香婷综合久久| 久久99精品久久久久久| 国产午夜福利精品久久| 精品国产综合区久久久久久| 久久免费大片| 国产精品一区二区久久精品涩爱 | 麻豆久久久9性大片| 欧美成a人片免费看久久| 色婷婷噜噜久久国产精品12p| 日韩精品久久久久久久电影| 亚洲综合熟女久久久30p| 97久久精品国产精品青草| 久久青青草原综合伊人| 久久夜色精品国产亚洲av| 亚洲AV日韩AV天堂久久| 久久精品成人免费看| 久久婷婷五月综合色99啪ak| 伊人久久综合无码成人网| 99久久99这里只有免费的精品| 国产精品一区二区久久精品无码| 欧美日韩精品久久免费| 婷婷综合久久狠狠色99h| 亚洲精品高清一二区久久| 久久久久99精品成人片欧美| 久久伊人亚洲AV无码网站| 久久综合九色综合网站| 久久久99精品一区二区| 99久久er这里只有精品18| 久久综合伊人77777| 久久九九有精品国产23百花影院| 香蕉aa三级久久毛片| 一级做a爰片久久毛片人呢| 亚洲va中文字幕无码久久不卡|