• <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
            呵呵,今天剛看到你給我博客的評論。

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

              回復  更多評論
              
            国产精品va久久久久久久| 伊人久久大香线蕉综合Av| 一本一道久久精品综合| 国产精品gz久久久| 久久91精品国产91久| 国产99久久久国产精品小说| 亚洲AV无码久久精品蜜桃| 久久国产精品无码HDAV| 久久久精品波多野结衣| 亚洲精品国产美女久久久| 国产精品久久网| 亚洲国产成人久久综合野外| 无码精品久久久天天影视| 久久九九有精品国产23百花影院| 久久久综合香蕉尹人综合网| 亚洲国产欧洲综合997久久| 99久久精品费精品国产| 97精品依人久久久大香线蕉97| 久久综合精品国产二区无码| 国産精品久久久久久久| 亚洲国产精品成人久久| 久久久久99精品成人片| 久久综合给合久久国产免费| 26uuu久久五月天| 97精品依人久久久大香线蕉97| 9191精品国产免费久久| 一本一本久久A久久综合精品| 久久91综合国产91久久精品| 精品久久久久久无码不卡| 91精品国产91久久| 国产精品久久久亚洲| 久久久久亚洲AV成人网人人网站| 久久久久国产精品| 久久久久亚洲av无码专区导航| 青青青青久久精品国产h久久精品五福影院1421 | 精品久久久久一区二区三区| 久久久久波多野结衣高潮| 久久久久国产一级毛片高清板| 久久精品中文闷骚内射| 97精品依人久久久大香线蕉97| 色偷偷91久久综合噜噜噜噜|