对象池头文件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;
}