1. 程式人生 > >STL配置器(allocator)簡介

STL配置器(allocator)簡介

假如有類Arwen,然後例項化該類

class Arwen { }

Arwen pWen = new Arwen; //這裡實際上背後分兩步執行.(1)呼叫operator new 配置記憶體 (2)呼叫Arwen::Arwen()構造物件內容

delete pWen;   //這裡背後也是兩步(1)呼叫Arwen:~Arwen()將物件析構 (2)呼叫operator delete釋放記憶體.

這裡的operator new 與C中的malloc對應,operator delete 與 C中的free對應.

STL中的allocator相當於顯式的來實現new運算子與delete運算子.總實現4個步驟.

(1)使用allocate來配置記憶體 , 使用deallocate來釋放記憶體

(2)使用construct來負責物件構造,使用destroy來析構物件.

當然了實際的實現中可沒這裡講的這麼簡單,複雜的多了.

記憶體分配(allocate)與記憶體釋放(deallocate)

記憶體分配

template<class T>

T* allocate(size_t size)

{

 T* tmp =  (T*) (operator new ( n*sizeof(T))  );//實際上你也可以用C中的malloc. T* tmp = (T*) malloc(n* sizeof(T) );

return tmp;

}

釋放記憶體

template<class T>

void deallocate(T* p) {

operator delete(p);   //如果前面用的malloc則是用free(p);

}

構造物件construct 與析構物件destroy

也就是顯式的去呼叫建構函式與解構函式.你可能會疑惑,我平常就使用一個new就完事,建構函式會被自動的呼叫到.如果顯式去呼叫可咋整啊?這裡就需要用到一個新概念叫placement new.關於new的三個相關的但又不同的概念:

(1)new (2)operator new (3) placement new

其中(1)new是我們最常用的,它不能被過載.使用它時總是會先自動呼叫operator new分配記憶體,然後呼叫建構函式初始化物件

(2)operator new就跟C中的malloc一樣,只是簡單的分配記憶體.例如 int* ip =(int*) operator new (sizeof(int) );

(3)placement new是operator new的一個過載版本.但它不會分配記憶體,只是返回已經分配的記憶體地址,並初始化該記憶體塊中的一些變數值.

所以我們是通過使用placement new來顯式的呼叫建構函式.用法如下:

template<class Ta , class Tb>

void construct(Ta* p , const Tb& value){

new (p) Ta(value);  //這就是所謂的placement new.樣子長的有點怪怪的吧.比一般的new多了個(p),這個p就是物件的記憶體地址了.

}

解構函式的話就簡單了啊

template<class T>

void destroy (T* p){

p->~T(); //直接呼叫解構函式就可以了.

}

你可能會納悶為啥解構函式直接呼叫就可以了啊,而直接呼叫建構函式會那麼麻煩.這我也沒搞懂.反正你可寫程式碼試下.就假如用說到的類Arwen.

Arwen* p = new Arwen;

p->Arwen(); //這樣直接呼叫建構函式肯定出錯

p->~Arwen(); //這樣呼叫解構函式是沒一點問題的.