如果我們想使內存管理器用于其他大小不同的類該怎么辦呢?為每一個類重復管理邏輯顯然是對開發時間的不必要浪費。如果我們看一下前面內存管理器的實現,就會明顯地看出內存管理邏輯實際上獨立于特定的類 有關的是對象的大小一這是內存池模板實現的良好候選。內存池將管理某種類型的一個可用對象池。模板實現將允許我們把管理的特定對象多樣化。
值得注意的是 到目前為止的內存配置器都是只支持單線程的 要對多線程支持得上鎖,下面固定大小 的大小是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);}