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(); //這樣呼叫解構函式是沒一點問題的.