《Effective C++》中的条款10 如果写了operator new就要同时写operator delete 一节
给出了一个很精妙的例子。给出了一个最简单的内存池的模型。
读起来让人真感觉的舒服。。。
实现方法就是 类中重载了operate new, delete 操作符。申请大内存,切分成小内存,依靠链表的形式组织起来。。反复利用。。貌似没有处理内存不够用时的动态增长内存的情况。
上代码:
// 类定义
class airplane { // 修改后的类 — 支持自定义的内存管理
public: //
static void * operator new(size_t size);
...
private:
union {
airplanerep *rep; // 用于被使用的对象
airplane *next; // 用于没被使用的(在自由链表中)对象
};
// 类的常量,指定一个大的内存块中放多少个
// airplane对象,在后面初始化
static const int block_size;
static airplane *headoffreelist;
};
// 重载new
void * airplane::operator new(size_t size)
{
// 把“错误”大小的请求转给::operator new()处理;
// 详见条款8
if (size != sizeof(airplane))
return ::operator new(size);
airplane *p = // p指向自由链表的表头
headoffreelist; //
// p 若合法,则将表头移动到它的下一个元素
//
if (p)
headoffreelist = p->next;
else {
// 自由链表为空,则分配一个大的内存块,
// 可以容纳block_size个airplane对象
airplane *newblock =
static_cast<airplane*>(::operator new(block_size *
sizeof(airplane)));
// 将每个小内存块链接起来形成一个新的自由链表
// 跳过第0个元素,因为它要被返回给operator new的调用者
//
for (int i = 1; i < block_size-1; ++i)
newblock[i].next = &newblock[i+1];
// 用空指针结束链表
newblock[block_size-1].next = 0;
// p 设为表的头部,headoffreelist指向的
// 内存块紧跟其后
p = newblock;
headoffreelist = &newblock[1];
}
return p;
}
// 传给operator delete的是一个内存块, 如果
// 其大小正确,就加到自由内存块链表的最前面
//
void airplane::operator delete(void *deadobject,
size_t size)
{
if (deadobject == 0) return; // 见条款 8
if (size != sizeof(airplane)) { // 见条款 8
::operator delete(deadobject);
return;
}
airplane *carcass =
static_cast<airplane*>(deadobject);
carcass->next = headoffreelist;
headoffreelist = carcass;
}