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

            組件
               這里實(shí)現(xiàn)了new_delete_policy_baseobject_pool_impl兩個(gè)基礎(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ī)制實(shí)現(xiàn)的內(nèi)存池,quick_object從new_delete_policy_base<mem_pool>繼承,用于演示定制new和delete的行為,_THROW_EXCEPTION宏用于屏蔽代碼,測試當(dāng)對象空間分配成功但構(gòu)造函數(shù)拋出異常時(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)行條件編譯可以。
            但是也可以自己來實(shí)現(xiàn)一個(gè)跨平臺的信號量。

              回復(fù)  更多評論
              
            久久国产精品免费一区| 久久婷婷成人综合色综合| 国产精品欧美久久久久天天影视| 国产91久久精品一区二区| 国内精品久久久久久中文字幕| 日本高清无卡码一区二区久久| 99精品久久久久久久婷婷| 色综合久久中文综合网| 一97日本道伊人久久综合影院| 国产综合久久久久久鬼色| 久久综合久久伊人| 2021国产成人精品久久| 国产69精品久久久久9999APGF| 亚洲国产精品久久久久网站| 亚洲AV日韩AV永久无码久久| 久久久久久av无码免费看大片| 久久亚洲日韩精品一区二区三区| 久久久久亚洲av毛片大| 久久99国产精品久久| 亚洲精品无码久久千人斩| 色欲综合久久躁天天躁| 久久精品国产亚洲沈樵| 久久综合香蕉国产蜜臀AV| 综合久久一区二区三区 | 久久久久亚洲AV成人网人人网站 | 久久久久人妻精品一区| 四虎国产精品成人免费久久| 久久精品国产黑森林| 91精品国产高清久久久久久国产嫩草 | 中文字幕无码av激情不卡久久| 青青草原综合久久| 狠狠狠色丁香婷婷综合久久五月 | 综合久久国产九一剧情麻豆| 色婷婷综合久久久久中文字幕| 91精品久久久久久无码| 国产精品18久久久久久vr| 色偷偷久久一区二区三区| 亚洲精品无码久久久久sm| 欧美亚洲色综久久精品国产| 亚洲精品高清国产一线久久| 伊人久久大香线蕉av不卡|