allocator
我们将前面说的operator new和operator delete放在一个封装好的类allocator中。
类的声明
class allocator{
private:
struct obj{
struct obj* next;
}
public:
void *allocate(size_t);
void deallocate(void *, size_t);
private:
obj* freeStore = nullptr;
const int CHUNK = 5;
}
void * allocator::allocate(size_t size){
obj* p;
if(!freeStore){
freeStore = p = (obj*)malloc(CHUNK * size);
for(int i = 0;i < CHUNK - 1;i++){
p->next = (obj*)((char*)p + size);
p = p->next;
}
p->next = nullptr;
}
p = freeStore;
freeStore = freeStore->next;
return p;
}
void allocate::deallocate(void* p, size_t){
((obj*)p)->next = freeStore;
freeStore = (obj*)p;
}
因此其他的类只需要声明allocator的对象就可以。
class FOO{
public:
long L;
string str;
static allocator myAlloc;
public:
FOO(long l):L(l){}
static void* operator new(size_t size){
return myAlloc.allocate(size);
}
static void operator delete(void *pdead, size_t size){
return myAlloc.deallocate(pdead, size);
}
};
allocate FOO::myAlloc;
在美各类里面进行声明的过程我们为了简化,我们可以采用宏声明的方式。
macro(宏定义)
宏本质上是代码片段打包形成的别名,程序在编译前的预处理的过程中,宏实际上会被替换成相应的代码片段。
#define DECLARE_POOL_ALLOC()\
public:\
void* operator new(size_t size){
return myAlloc.allocate(size);
}\
void operator delete(void *pdead){
return myAlloc.deallocate(pdead, 0);
}\
protected:\
static allocator myAlloc;
#define IMPLEMENT_POOL_ALLOC(class_name)\
allocator class_name::myAlloc
上面的类的声明就变成了,我们只需要传进去类的名称就好了。
class FOO(){
DECLARE_POOL_ALLOC();
public:
long L;
string str;
public:
FOO(long l):L(l){}
};
IMPLEMENT_POOL_ALLOC(FOO)