• <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>
            隨筆-161  評論-223  文章-30  trackbacks-0
            引言
               在面向?qū)ο箢惖脑O(shè)計中,有時為了強(qiáng)化效能,特別是當(dāng)構(gòu)造大量小對象時,為了改善內(nèi)存碎片,就需要自己實現(xiàn)對象的內(nèi)存管理,以替換系統(tǒng)缺省的分配和釋放行為,即全局的new和delete。按照c++標(biāo)準(zhǔn),在定制類專屬的new和delete時,為了減免客戶代碼使用時的麻煩和問題,需要考慮同時定制簡單(normal new)定位(placement new)無異常(nothrow new)三種new情形,以及與之配對的三種delete情形,另外還有對應(yīng)的數(shù)組new[]和delete[]各三種情形。在接口設(shè)計上,每種情形都是operator new和operator delete的重載版本;在內(nèi)存管理上,具體的對象空間分配和釋放是靈活的,因此這一部分可實現(xiàn)為策略模式,通過改變替換不同的內(nèi)存管理策略,即可輕易獲得不同的內(nèi)存分配和釋放行為,而類的代碼則無須改變。為了方便定制類的new和delete,可以從一個接口基類模板繼承而自動獲得這種特性。這個基類模板實現(xiàn)了單個對象的new、delete和對象數(shù)組的new、delete,而模板參數(shù)正是內(nèi)存管理策略類,它的設(shè)計約束如下:
               1)必須存在static成員方法mallocfree,其參數(shù)和返回值與C庫的malloc和free一致。
               2)malloc只分配空間,若分配成功則不必初始化,否則失敗返回NULL,不能拋出異常,因為normal new的語義為對于分配失敗則拋出std::bad_alloc異常,而nothrow new則返回NULL,如此兩種方式兼?zhèn)?,有利于客戶代碼的按需靈活檢測;free只釋放或歸還空間。
               3)malloc和free的內(nèi)部實現(xiàn)是靈活的,由應(yīng)用開發(fā)者定制。

            組件
               這里實現(xiàn)了new_delete_policy_baseobject_pool_impl兩個基礎(chǔ)組件,代碼如下,前者是支持內(nèi)存管理策略的定制new和delete接口基類模板,從該類繼承的子類其對象的構(gòu)造和析構(gòu)就被定制了;后者是支持內(nèi)存管理策略的非侵入式對象池類模板,可直接用于構(gòu)造某類的對象,包括內(nèi)建的基本數(shù)據(jù)類型,而該類不必從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}
            ;

            應(yīng)用
               下面代碼中的mem_pool是一種基于自由列表機(jī)制實現(xiàn)的內(nèi)存池,quick_object從new_delete_policy_base<mem_pool>繼承,用于演示定制new和delete的行為,_THROW_EXCEPTION宏用于屏蔽代碼,測試當(dāng)對象空間分配成功但構(gòu)造函數(shù)拋出異常時,對應(yīng)的operator delete是否得到調(diào)用,而保證釋放內(nèi)存空間,normal_object是空類,它不從new_delete_policy_base<mem_pool>繼承,用于演示對象池構(gòu)造和銷毀對象的行為。
             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 春秋十二月 閱讀(2087) 評論(2)  編輯 收藏 引用 所屬分類: C/C++

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

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

              回復(fù)  更多評論
              
            久久丫精品国产亚洲av不卡| 久久99精品久久久久久秒播| 久久亚洲中文字幕精品一区四| 久久99精品久久久久久齐齐| 日本久久久久久久久久| 欧美久久久久久午夜精品| 麻豆av久久av盛宴av| 日本久久久久亚洲中字幕 | 久久久无码精品亚洲日韩软件| 亚洲性久久久影院| www性久久久com| 亚洲欧洲久久久精品| 久久综合九色综合精品| 亚洲国产成人久久综合碰| 久久久久99精品成人片欧美| 久久精品国产精品亜洲毛片| 久久国产欧美日韩精品| 99久久精品无码一区二区毛片 | 久久精品毛片免费观看| 久久se精品一区精品二区国产 | 久久精品国产亚洲AV蜜臀色欲| 99久久精品国产麻豆| 久久成人小视频| 久久99精品国产麻豆蜜芽| 97久久精品无码一区二区| 久久精品一区二区三区AV| 国产免费久久精品99久久| 香蕉久久av一区二区三区| 久久人人爽人人爽人人片AV东京热| 精品无码久久久久久尤物| 色老头网站久久网| 久久国产免费直播| 久久久久久国产a免费观看不卡| 精品久久久久久成人AV| 久久久久久久精品成人热色戒| 狠狠久久综合| 精品久久久久中文字幕一区| 热久久这里只有精品| 久久综合中文字幕| 久久精品人人做人人爽电影蜜月| 久久精品国产色蜜蜜麻豆|