首页>
知识库>
详情

重构的力量2-对象池

2020-07-02 来源:CloudBest 阅读量: 0
关键词:

    经过一天的思考后,决定还是把变量k(也就是每一内存页中对象的数量)放在构造函数中,因为这个变量需要调整以取得最佳性能,而如果程序中定义了大量的TObjectPool<T,k>::Ptr后,调整k值,这些定义语句也要写改,所以把它从模版参数移入构造函数中,这样改动k值只需改写一句程序就可以了。
    #ifndef _TObjectPoolV12_H_
    #define _TObjectPoolV12_H_
    #include<iostream>
    #pragma warning(disable: 4786)//关闭4786错误(STL调试信息过长,超过255字符)
    #include<list>
    #include<algorithm>
    namespace Aura
    {
    //TObjectPool1.2
    //对象池模版,池里分配预算定数量的对象,用时从池申请,不用时归还池,采用页链表技术使池理论无上限
    //错误信息
    enum TObjectPool_error
    {
    TObjectPool_error_no,
    TObjectPool_error_memory,      //内存分配错误
    TObjectPool_error_null_pointer,    //无效指针
    TObjectPool_error_multiple_return,  //重复归还
    };
    const static char* TObjectPool_error_strings_A[] = {
    "正常",
    "内存分配错误",
    "无效指针",
    "重复归还"};
    const static wchar_t* TObjectPool_error_strings_W[] = {
    L"正常",
    L"内存分配错误",
    L"无效指针",
    L"重复归还"};
    #ifdef UNICODE
    #define TObjectPool_error_strings TObjectPool_error_strings_W
    #else
    #define TObjectPool_error_strings TObjectPool_error_strings_A
    #endif
    template <typename T>
    class TObjectPool
    {
    private:
    class page;
    public:
    //proxy classes
    class Ptr
    {
    public:
    friend class page;
    Ptr():m_p(NULL){}
    ~Ptr(){}
    T* operator->()const{return m_p;}
    T& operator*()const{return *m_p;}
    operator bool()const{return NULL!=m_p;}
    private:
    Ptr(T* p){}
    Ptr(const Ptr& rhs){}
    Ptr& operator=(const Ptr& rhs){}
    T* m_p;
    };
    public:
    TObjectPool(unsigned long per_page_object_count=16);
    ~TObjectPool();
    //申请一个对象
    bool operator 》(Ptr& ptr);
    //归还一个对象(注意:归后ptr为NULL值)。
    bool operator 《(Ptr& ptr);
    //获取错误代码
    TObjectPool_error error()const{return m_error;}
    private:
    class page
    {
    public:
    page(unsigned long k)
    :m_object_count(k),m_objects(0),m_objects_statck(0),m_objects_idle_flag(0),m_memory_error(false)
    {
    if(NULL==(m_objects=new T[m_object_count])){set_memory_error();return;}
    if(NULL==(m_objects_statck=new T*[m_object_count])){set_memory_error();return;}
    if(NULL==(m_objects_idle_flag=new bool[m_object_count])){set_memory_error();return;}
    for(m_statck_top=0; m_statck_top<m_object_count; ++m_statck_top)
    {
    m_objects_statck[m_statck_top]=&m_objects[m_statck_top];
    m_objects_idle_flag[m_statck_top]=true;
    }
    }
    ~page(){release();}
    void release()
    {
    if(NULL!=m_objects)delete[] m_objects;
    if(NULL!=m_objects_statck)delete[] m_objects_statck;
    if(NULL!=m_objects_idle_flag)delete[] m_objects_idle_flag;
    }
    void set_memory_error(){m_memory_error=true;release();}
    bool memory_error()const{return m_memory_error;}
    bool is_empty()const{return 0==m_statck_top;}
    bool is_full()const{return m_statck_top==m_object_count;}
    bool is_member(const Ptr& ptr){return (