• <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>

            5D空間

            學習總結與經驗交流

               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              對象池的指針版本。池中本質上是一群對象,只構造一次,返回指針。主要支持頻繁重建的內存空間不連續的自建結構,如樹,鏈表。
            /******************************************************************
             *名稱:PointerPool(指針池)(模板)
             *版本號:0.1
             *作者:趙耀(中山大學2010級)
             *時間:2011.4.11
             *簡介:
             *        對應于對象池,這是一個指針池,用于緩存頻繁調用的指針(對象).主要支
             *    持頻繁重建的樹或鏈表等結構.具有默認構造函數接收一個size_t對象表明指針
             *    分塊的大小,默認為10.接收的參數如果<=0則會拋出異常invalid_argument.
             *    public方法:
             *        T* getPointer(); 從池中返回一個該類型對象的指針;
             *        void recyclePointer( T* ); 接受需要回收的指針;
             *        void clear(); 清空池以釋放占用的內存;
             *        bool empty(); 返回池是否為空;
             *        size_t size(); 返回池中總指針數量;
             *        size_t remain(); 返回指針池剩余可用指針的數量;
             *    注意:
             *        使用方法可簡單地想成通過兩個成員函數來代替new和delete.必須確保分
             *    配的指針得到回收!必須確保回收的指針不是外來指針!因為未進行二次初始化,
             *    重新分配得到的指針所指對象可能是上一次使用后的殘余對象,請進行必要的初
             *    話工作.
             *
             *未完成特性:
             *        因為主要支持樹,鏈表等內存空間不連續的結構,所以未實現成數組規模
             *    地分配指針的功能.
             *
             *已知bug:暫無
             *
             *版權信息:
             *        該代碼為開源代碼,原作者保留其所有權.你可以拷貝,修改,使用該代碼,但
             *    是請保留必要的版權信息.
            *****************************************************************
            */

            #ifndef POINTERPOOL_H
            #define POINTERPOOL_H

            #include 
            <vector>
            #include 
            <queue>
            #include 
            <stdexcept>
            #include 
            <memory>
            using namespace std;

            template
            < typename T >
            class PointerPool
            {
            public:
                
            //Create a PointerPool to contain size pointers.
                PointerPool( size_t size = kDefaultChunkSize )
                    
            throw ( invalid_argument, bad_alloc );
                
            ~PointerPool();

                
            //Return a specific pointer to client.
                T *getPointer();
                
            //Recycle the pointer that the client doesn't need any more.
                void recyclePointer( T* );
                
            //Clear the pool and release the memory.
                void clear();
                
            bool empty();
                
            //Return the total number of pointers the pool contains.
                size_t size();
                
            //Return the number of pointers remain available.
                size_t remain();

            protected:
                queue
            < T* > mFreeList;
                vector
            < T* > mAllpointers;//A record of all pointers which help
                
            //to destroy them.

                size_t mChunkSize;
                
            static const size_t kDefaultChunkSize = 10;

                
            //Allocate mChunkSize new pointers and add them to the
                
            //mFreeList.
                void allocateChunk();
                
            //help the destructor the delete the pointers int the pool.
                static void deleteHelper( T* );

            private:
                
            //Hide the copy constructor and assignment symbol.
                PointerPool( const PointerPool< T > & );
                PointerPool
            < T > &operator=const PointerPool< T > & );
            }
            ;

            template
            < typename T >
            size_t PointerPool
            <T>::remain()
            {
                
            return mFreeList.size();
            }


            template
            < typename T >
            bool PointerPool<T>::empty()
            {
                
            return remain() == 0;
            }


            template
            < typename T >
            size_t PointerPool
            <T>::size()
            {
                
            return mChunkSize * mAllpointers.size();
            }


            template
            < typename T >
            PointerPool
            <T>::PointerPool( size_t size /*= kDefaultChunkSize */ ) throw ( invalid_argument, bad_alloc )
            {
                
            if ( size <= 0 )
                    
            throw invalid_argument( "chunk size must be positive" );

                mChunkSize 
            = size;
                allocateChunk();
            }


            template
            < typename T >
            *PointerPool<T>::getPointer()
            {
                
            if ( mFreeList.empty() )
                    allocateChunk();

                T 
            *ptr = mFreeList.front();
                mFreeList.pop();
                
            return ptr;
            }


            template
            < typename T >
            void PointerPool<T>::clear()
            {
                for_each( mAllpointers.begin(), mAllpointers.end(), deleteHelper );

                mAllpointers.clear();
                
            while ( !mFreeList.empty() )
                    mFreeList.pop();
            }


            template
            < typename T >
            void PointerPool<T>::recyclePointer( T *ptr )
            {
                mFreeList.push( ptr );
            }


            template
            < typename T >
            void PointerPool<T>::allocateChunk()
            {
                T
            * newPointerChunk = new T[ mChunkSize ];

                mAllpointers.push_back( newPointerChunk );
                
            for ( int i = 0; i < mChunkSize; i++ )
                
            {
                    mFreeList.push( 
            &newPointerChunk[i] );
                }

            }


            template
            < typename T >
            void PointerPool<T>::deleteHelper( T *pointerChunk )
            {
                delete [] pointerChunk;
            }


            template
            < typename T >
            PointerPool
            <T>::~PointerPool()
            {
                for_each( mAllpointers.begin(), mAllpointers.end(), deleteHelper );
            }


            #endif

            以下為測試代碼:
            #include "PointerPool.h"
            #include 
            <iostream>
            using namespace std;

            class ListNode
            {
            public:
                
            int value;
                ListNode 
            *nextPtr;

                ListNode() : value(
            0), nextPtr(0)
                
            {}
            }
            ;

            int growing()
            {
                
            static int numGrouwing = 0;
                
            return numGrouwing++;
            }


            int main()
            {
                
            const int cases = 2;
                PointerPool
            < ListNode > lnPool;

                
            //Make 2 tests.
                for ( int i = 0; i < cases; i++ )
                
            {
                    
            if ( lnPool.empty() )
                        cout 
            << "The pool is empty!" << endl;
                    
            else
                        cout 
            << "The pool has " << lnPool.remain()
                        
            << " pointers available" << endl;

                    
            //Create the head of a list.
                    ListNode *start = lnPool.getPointer();
                    start
            ->value = growing();
                    ListNode 
            *last = start;

                    
            //Complete the list with length of 100.
                    for ( int j = 1; j < 100; j++ )
                    
            {
                        ListNode 
            *tmp = lnPool.getPointer();
                        tmp
            ->value = growing();
                        last
            ->nextPtr = tmp;
                        last 
            = tmp;
                    }


                    
            //Travel and cout the value of each node.
                    ListNode *current = start;
                    
            while ( current != 0 )
                    
            {
                        cout 
            << current->value << '\t';
                        current 
            = current->nextPtr;
                    }


                    
            //Recycle all pointers back to the pool.
                    while ( start != 0 )
                    
            {
                        current 
            = start;
                        start 
            = start->nextPtr;
                        lnPool.recyclePointer( current );
                    }


                    cout 
            << "The pool has " << lnPool.size() << " pointers"
                        
            << "\n\n";
                    
            //Try clear the pool
                    lnPool.clear();
                }

            }
            posted on 2011-04-11 16:13 今晚打老虎 閱讀(1857) 評論(5)  編輯 收藏 引用 所屬分類: 我的開源庫

            評論

            # re: PointerPool(指針池) 2011-04-11 18:26 ooseven
            本質上就是一個ptrvector吧?  回復  更多評論
              

            # re: PointerPool(指針池) 2011-04-11 18:49 bennycen
            。。。。。。。。。  回復  更多評論
              

            # re: PointerPool(指針池) 2011-04-11 20:42 千暮(zblc)
            測試了下,如果把鏈表長度改為1w,kDefaultChunkSize長度改為100,注釋掉所有輸出,cases改為2w 比不用你的指針池而直接new快4-5倍.

              回復  更多評論
              

            # re: PointerPool(指針池) 2011-04-12 00:19 今晚打老虎
            @千暮(zblc)
            感謝測試。其實我還在c++的摸爬滾打中,對性能測試的概念還比較模糊,也沒有學習和體驗過系統的測試。希望能得到有關方面的指教,比如,測試工具需要什么么?參考指標有哪些?  回復  更多評論
              

            # re: PointerPool(指針池) 2011-04-12 00:46 千暮(zblc)
            @今晚打老虎
            其實不用考慮得太復雜 就是計算時間(在代碼中插入時鐘計算間隔)、空間消耗(重載分配堆內存的內置函數)和運行效率的穩定性(代碼運行的邊界情況進行分析)。至于系統測試,也只是把情況劃分得更加細致而已。  回復  更多評論
              

            久久精品无码一区二区无码| 色综合久久天天综线观看| 中文字幕精品无码久久久久久3D日动漫| 丰满少妇人妻久久久久久| 奇米影视7777久久精品| 中文字幕日本人妻久久久免费 | 欧美激情精品久久久久久| 91精品国产色综久久 | 久久er99热精品一区二区| 久久综合狠狠综合久久| 久久发布国产伦子伦精品| 久久成人国产精品二三区| 精品无码久久久久久国产| 亚洲国产成人久久笫一页| 亚洲精品tv久久久久| 久久亚洲国产成人影院| 亚洲精品无码久久久久久| 久久久久久亚洲Av无码精品专口| 久久99国产精品尤物| 丰满少妇人妻久久久久久4| 久久久人妻精品无码一区| 久久久久亚洲AV无码专区首JN| 无码久久精品国产亚洲Av影片 | 国产 亚洲 欧美 另类 久久| 人人狠狠综合久久亚洲| 午夜久久久久久禁播电影| 久久天堂电影网| 日本加勒比久久精品| 久久亚洲美女精品国产精品| 精品午夜久久福利大片| 日韩欧美亚洲国产精品字幕久久久 | 色婷婷久久综合中文久久蜜桃av| 久久久精品国产sm调教网站 | 久久久久亚洲AV综合波多野结衣| 国内精品久久久久影院老司| 久久久久高潮毛片免费全部播放 | 青青草原1769久久免费播放| 久久综合久久综合亚洲| 国产精品久久久久久一区二区三区| 性高朝久久久久久久久久| 2021精品国产综合久久|