当前位置: 代码迷 >> 综合 >> 对象池
  详细解决方案

对象池

热度:40   发布时间:2024-02-21 20:45:46.0

对象池头文件CELLObjectPool.h

#ifndef _CELLObjectPool_hpp_
#define _CELLObjectPool_hpp_

#include<stdlib.h>
#include<iostream>
#include<mutex>
#include<assert.h>
using namespace std;


template<class Type,size_t nPoolSize>
class CELLObjectPool
{public:

    CELLObjectPool(){
        _pBuf = nullptr;   
    
    }
    ~CELLObjectPool(){
        if (!_pBuf)
            delete[] _pBuf;
        
    }
private:
    struct NodeHeader{
    public:

        //内存块编号
        int nID;
        //引用次数
        int nRef;
        // 下一块位置
        NodeHeader* pNext;
        //是否在内存池中
        bool bPool;

    private:
        //预留
        char c1;
        char c2;

    };
private:

    NodeHeader* _pHeader;

    //对象池内存缓冲区地址
    char* _pBuf;
    std::mutex _mutex;
public:
    

    //释放对象
    void freeObjMemory(void* pMem){

        //传进来的值没有NodeHeader的包头
        //所以传进来的指针需要向左移动sizeof(NodeHeader)个字节
        NodeHeader* pBlock = (NodeHeader*)((char*)pMem - sizeof(NodeHeader));

        assert(1 == pBlock->nRef);
        if (pBlock->bPool){
            std::lock_guard<std::mutex> lg(_mutex);
            if (--pBlock->nRef != 0)
                return;

            
            pBlock->pNext = _pHeader;
            _pHeader = pBlock;

        }
        else{
            if (--pBlock->nRef != 0)
                return;
            delete[] pBlock;
        }

    }

    //申请对象
    void*  allocObjMemmory(size_t Size){


        if (nullptr == _pBuf){
            initPool();

        }
        std::lock_guard<std::mutex> lg(_mutex);

        NodeHeader* pReturn = nullptr;
        if (nullptr == _pHeader){

            pReturn = (NodeHeader*)new char(sizeof(Type)+ sizeof(NodeHeader));
            pReturn->bPool = false;
            pReturn->nID = -1;
            pReturn->nRef = 1;
            pReturn->pNext = nullptr;


        }
        else{

            pReturn = _pHeader;
            _pHeader = _pHeader->pNext;
            //断言
            assert(0 == pReturn->nRef);
            pReturn->nRef = 1;

        }
        //返回的内存空间也没有NodeHeader的包头
        return ((char*)pReturn + sizeof(NodeHeader));
    }


    //初始化对象池
    void initPool()
    {
        assert(nullptr == _pBuf);
        if (nullptr != _pBuf)
            return;

        //计算对象池的大小

        size_t realSize=sizeof(Type)+sizeof(NodeHeader);
        size_t n = nPoolSize*realSize;
        
        _pBuf = new char[n];

        //初始化对象池

        _pHeader = (NodeHeader*)_pBuf;
        _pHeader->bPool = true;
        _pHeader->nID = 1;
        _pHeader->nRef = 0;
        _pHeader->pNext = nullptr;

        NodeHeader* pTemp1 = _pHeader;

        for (size_t n = 2; n < nPoolSize; n++){

            NodeHeader* pTemp2 = (NodeHeader*)(_pBuf + (n*realSize));

            pTemp2->bPool = true;
            pTemp2->nID = n;
            pTemp2->nRef = 0;
            pTemp2->pNext = nullptr;
            pTemp1->pNext = pTemp2;
            pTemp1 = pTemp2;

        }
    }


private:

};

 

 

template <class Type,size_t nPoolSize>
class ObjectPoolbase{
public:
    
    void* operator new(size_t Size){
        
        return objectPool().allocObjMemmory(Size);

    }

    void operator delete(void* p){
        
        objectPool().freeObjMemory(p);

    }

    // 模板函数,不定参数可传入
    template<typename ...Args>
    static Type* createObject(Args ... args){
        Type* obj = new Type(args...);
        return obj;
    }


    static void destoryObject(Type* obj){

        delete obj;
    }

private:
    typedef CELLObjectPool<Type, nPoolSize> classTypePool;
    static classTypePool& objectPool(){
        //静态池
        static classTypePool sPool;
        return sPool;
    }

};


#endif

 

主函数:class A和B申请对象池,当用户申请对象A或者B时,可以直接从池中申请,当申请其他对象时,需要直接向内存申请。当池中的内存用完时,也可以向内存申请。(主要思想与内存池相似)

 

#include<iostream>
#include"Alloctor.h"
#include<memory>
#include"CELLObjectPool.h"


using namespace std;

class A :public ObjectPoolbase <A,10> {
public:
    A(){
        Anum = 0;
        printf("A created\n");

    }

    ~A(){
        printf("A deleted\n");
    }

    

private:
    int Anum;
};


class B :public ObjectPoolbase<B,10> {
public:
    B(int Num){
        num = Num;
        printf("B created\n");
    }

    ~B(){
        printf("B deleted\n");
    }


public:

    int num;
};


int main(){


    A* a2 = A::createObject();
    A::destoryObject(a2);

    B* bb = new B(2);
    delete bb;

    B* b2 = B::createObject(2);
    B::destoryObject(b2);

 

    system("pause");
    return 0;
}

  相关解决方案