1. 程式人生 > >STL源碼剖析之allocator(2)

STL源碼剖析之allocator(2)

內部 擁有 struct trait 多個 接受 rst stl -m

SGI雖然定義了名為allocator的配置器,但從未使用過。SGI的allocator只是包裝了C++的::operatpor new和::operator delete,效率不高。STL中內存配置操作由alloc::allocate()負責,內存釋放操作由alloc::deallocate()負責;對象構造操作由::construct()負責,對象析構操作由::destroy()負責。
STL配置器定義於頭文件

#include <stl_alloc.h>    //負責內存空間的配置與釋放
#include <stl.construct.h>    //負責對象內容的構造與析構

構造和析構:construct() 和 destroy()

construct函數內部使用placement new完成對象的構造:

template<class T1, class T2>
inline void construct(T1 *p, const T2& value)
{
    new (p) T1(value);
}

destroy函數擁有多個版本實現:

template<class T>
inline void destory(T* pointer)
{
    pointer->~T();    //調用析構函數
}

//接受兩個叠代器,對區間的destory操作
template<class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{
    __destroy(first, last, value_type(first));
}

//針對不同型別調用不同的__destory_aux函數
template<class ForwardIterator, class T>
inline void __destory(ForwardIterator first, ForwardIterator last, T*)
{
    typedef typename __type_traits<T>::has_trival_destructor trival_destructor;
    __destroy_aux(first, last, trival_destructor());
}

//擁有non-trival destructor的版本
template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type)
{
    for(; first < last; ++first)
        destroy(&*first);       //對區間每一個對象執行析構
}

//擁有trival destructor的版本
template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __true_type)
{
    //什麽都不做
}

//以下是destroy()針對叠代器為char* 和w_char*的特化版
inline void destroy(char*, char*) {}
inline void destroy(w_char*, w_char*) {}

總結上面的代碼,construct函數接受一個指針p和一個初值value,其用途是將初值寫到指針開始的位置上,這個操作可以通過C++的placement new完成。destroy函數擁有兩個版本:一個對指針指向對象做析構;另一個對區間做操作:如果區間元素有non-trival的析構函數,那麽對區間每一個元素執行析構操作,否則什麽都不做。destory函數的第二個版本通過value_type宏獲取叠代器所指對象的型別,傳遞給__destory函數;在_destory函數內部通過__value_traits來確定該型別的析構函數是否是trival,通過重載函數_destory_aux來決定是否要調用析構操作。

STL源碼剖析之allocator(2)