如果我们想使内存管理器用于其他大小不同的类该怎么办呢?为每一个类重复管理逻辑显然是对开发时间的不必要浪费。如果我们看一下前面内存管理器的实现,就会明显地看出内存管理逻辑实际上独立于特定的类 有关的是对象的大小一这是内存池模板实现的良好候选。内存池将管理某种类型的一个可用对象池。模板实现将允许我们把管理的特定对象多样化。
值得注意的是 到目前为止的内存配置器都是只支持单线程的 要对多线程支持得上锁,下面固定大小 的大小是allocate_1 的大小为基准。
#include <new> // placement new
#include <cstddef> // ptrdiff_t size_t
#include <cstdlib> // exit
#include <climits> // UINT_MAX
#include <iostream> // cerr
template<typename T>
class allcator_1
{public:typedef T value_type;typedef T* pointer;typedef const T* const_pointer;typedef T& reference;typedef const T& const_reference;typedef size_t size_type;typedef ptrdiff_t difference_type;public:static pointer allocate(size_type n, const void* hint = 0){return static_cast<pointer>(operator new(n));}static void deallocate(pointer ptr) {operator delete(static_cast<void*>(ptr));}static void construct(pointer ptr) {new (ptr) T;}static void destroy(pointer ptr) {ptr->~T();}
private:struct obj {unsigned long mile;char type;};union{obj b;allcator_1* next;};public:unsigned long getMiles() { return b.mile; }char getType() { return b.type; }void set(unsigned long m, char t) {b.mile = m;b.type = t;}static void* operator new(size_t size);static void operator delete(void* phead);static int m_iCount;// 用于分配计数统计,每new一次 + 1static int m_iMallocCount;//用于统计ma11oc次数,每ma11oc一次+1
private:static allcator_1* m_FreePosi;// 总是指向一块可以分配出去的内存的首地址static int m_sTrunkCount;//一次分配多少倍该类的内存
};
template<typename T>
void* allcator_1<T>::operator new(size_t size)
{allcator_1* p = m_FreePosi;if (p) //如果p有效就把链表头部向下移m_FreePosi = p->next;else{//如果链表已空,申请一大块内存int size = (sizeof(allcator_1) > sizeof(T)) ? sizeof(allcator_1) : sizeof(T);allcator_1* newBlock = static_cast<allcator_1*>(::operator new(m_sTrunkCount * size));//将小块穿成一个freelistfor (int i = 1; i < m_sTrunkCount - 1; ++i)newBlock[i].next = &newBlock[i + 1];newBlock[m_sTrunkCount - 1].next = 0;p = newBlock;m_FreePosi = &newBlock[1];}return p;
}
template<typename T>
void allcator_1<T> :: operator delete(void* phead)
{//free(phead);//不再用传统方式实现,针对内存池有特别的实现(static_cast <allcator_1*>(phead))->next = m_FreePosi;m_FreePosi = static_cast <allcator_1*>(phead);
}
template<typename T>
int allcator_1<T>::m_iCount = 0;
template<typename T>
int allcator_1<T>::m_iMallocCount = 0;
template<typename T>
allcator_1<T>* allcator_1<T>::m_FreePosi = nullptr;
template<typename T>
int allcator_1<T>::m_sTrunkCount = 5;
//一次分配5倍的该类内存作为内存池的大小class MyClass
{
public:MyClass();~MyClass();void getA() {std::cout << a << std::endl;}private:int a;int b;int c;};MyClass::MyClass():a(100),b(200),c(300)
{std::cout << "MyClass()" << std::endl;}MyClass::~MyClass(){getA();std::cout << "~MyClass()" << std::endl;
}
int main() {allcator_1<MyClass> alloc;MyClass* m = alloc.allocate(4);printf("%p\n", m);alloc.construct(m);alloc.destroy(m);alloc.deallocate(m);}