如果内存池将管理某一类型的可用对象池,模板实现将允许我们灵活地改变所管理的特定对象
#include <iostream>
#include <stdlib.h>
using std::cout;
using std::endl;
template <class T>
class MemoryPool
{
public:
MemoryPool(size_t size = EXPANSION_SIZE);
~MemoryPool();
inline void *alloc(size_t size);
inline void free(void *someElement);
private:
MemoryPool<T> *next;
enum { EXPANSION_SIZE = 32 };
void expandTheFreeList(int num = EXPANSION_SIZE);
};
template <class T>
MemoryPool<T>::MemoryPool(size_t size)
{
expandTheFreeList(size);
}
template <class T>
MemoryPool<T>::~MemoryPool()
{
MemoryPool<T> *nextPtr = next;
for (nextPtr = next; nextPtr != NULL; nextPtr = next)
{
next = next->next;
delete []nextPtr;
}
}
template <class T>
inline void * MemoryPool<T>::alloc(size_t size)
{
if (NULL == next)
expandTheFreeList();
MemoryPool<T> *head = next;
next = head->next;
return head;
}
template <class T>
inline void MemoryPool<T>::free(void *doomed)
{
MemoryPool<T> *head = reinterpret_cast<MemoryPool<T> *>(doomed);
head->next = next;
next = head;
}
template <class T>
void MemoryPool<T>::expandTheFreeList(int num)
{
size_t size = (sizeof(T) > sizeof(MemoryPool<T> *)) ? sizeof(T) : sizeof(MemoryPool<T> *);
MemoryPool<T> *runner = reinterpret_cast<MemoryPool<T> *>(new char[size]);
next = runner;
for (int i = 0; i < num; ++i)
{
runner->next = reinterpret_cast<MemoryPool<T> *>(new char[size]);
runner = runner->next;
}
runner->next = NULL;
}
// Rational类不再需要维护它自己的空间列表,这项任务委托给了MemoryPool类
class Rational
{
public:
Rational(int a = 0, int b = 1) : n(a), d(b) { }
void *operator new(size_t size) { memPool->alloc(size); }
void operator delete(void *doomed, size_t size) { memPool->free(doomed); }
static void newMemPool() { memPool = new MemoryPool<Rational>; }
static void deleteMemPool() { delete memPool; }
private:
int n;
int d;
static MemoryPool<Rational> *memPool;
};
MemoryPool<Rational> * Rational::memPool = NULL;
int main()
{
Rational *arr[1000] = { NULL };
Rational::newMemPool();
for (int k = 0; k < 500; ++k)
{
for (int i = 0; i < 1000; ++i)
arr[i] = new Rational(i);
for (int j = 0; j < 1000; ++j)
delete arr[j];
}
return 0;
}