当你受困于必须为不同的classes冲洗一遍几乎相同的member operator new 和 member operator delete时,应该有方法将一个总是分配特定尺寸之品魁的memory allocator概念包装起来,使它容易被重复使用。以下展示一种作法,每个allocator objec都是个分配器,它体内维护一个free-lists:不同allocator objects维护不同的free-lists
#include <iostream>
#include <complex.h>
using namespace std;
namespace liuqi {
class allocator {
private:
struct obj {
struct obj* next; //embedded pointer
};
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) {
size_t chunk = CHUNK * size;
freeStore = p = (obj*)malloc(chunk);
for(int i=0; i<(CHUNK-1); ++i) {
p->next = (obj*)((char*)p + size);
p = p->next;
}
p->next = nullptr; // last
}
p = freeStore;
freeStore = freeStore->next;
return p;
}
void allocator::deallocate(void* p, size_t size) {
((obj*)p)->next = freeStore;
freeStore = (obj*)p;
}
};
class Foo {
public:
long L;
string str;
static liuqi::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);
}
};
liuqi::allocator Foo::myAlloc;
class Goo {
public:
complex<double> c;
string str;
static liuqi::allocator myAlloc;
public:
Goo(const complex<double> x): c(x) {
}
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);
}
};
liuqi::allocator Goo::myAlloc;
int main() {
Foo* p[100];
cout << "sizeof(Foo)= " << sizeof(Foo) << endl;
for(int i=0; i<23; ++i) {
p[i] = new Foo(i);
cout << p[i] << ' ' << p[i]->L << endl;
}
for(int i=0; i<23; ++i) {
delete p[i];
p[i] = NULL;
}
Goo* pp[100];
cout << "sizeof(Goo)= " << sizeof(Goo) << endl;
for(int i=0; i<17; ++i) {
pp[i] = new Goo(complex<double>(i, i));
cout << pp[i] << ' ' << pp[i]->c << endl;
}
for(int i=0; i<17; ++i) {
delete pp[i];
pp[i] = NULL;
}
return 0;
}
这比先前的设计干净多了,application classes不再内存分配细节纠缠不清,所有相关细节都让allocator去操心,我们的工作是让application classes正确工作