C++ 空間配置器allocator類


allocator類

C++中,內存分配和對象構造緊密糾纏(new),就像對象析構和回收一樣(delete)。如果程序員想接管內存分配,即將內存分配和對象構造分開,對於前者,主要是分配和釋放未構造的原始內存;對於后者,主要是在原始內存中構造和撤銷對象。

 

分配和釋放未構造的原始內存 兩種方法:

  • allocator類,提供可感知類型的內存分配;
  • 標准庫中的opeator new和operator delete,它們分配和釋放需要大小的原始、未類型化的內存;

 

在原始內存中構造和撤銷對象 不同方法:

  • allocator類定義了名為construct和destroy的成員;
  • placement new表達式,接受指向未構造內存的指針;
  • 直接調用對象的析構函數來撤銷對象;
  • 算法uninitialized_fill 和 uninitialized_copy,在目的地構造對象;

 

C++的STL中定義了很多容器,容器的第二個模板參數通常為allocator類型,標准庫中allocator類定義在頭文件memory中,用於幫助將內存分配和對象的構造分離開來。它分配的內存是原始的、未構造的。

 

表達式 說明
allocator<T> a  定義了一個名為a的allocator對象,它可以為類型T的對象分配內存
a.allocator(n)  分配一段原始的、未構造的內存,這段內存能保存n個類型為T的對象
a.deallocate(p, n)

釋放T*指針p地址開始的內存,這塊內存保存了n個類型為T的對象,p必須是一個先前由allocate返回的指針,

且n必須是p創建時所要求的大小,且在調用該函數之前必須銷毀在這片內存上創建的對象。

a.construct(p, t) 在T*指針p所指向內存中構造一個新元素。運行T類型的復制構造函數用t初始化該對象
a.destory(p)  運行T*指針p所指向對象的析構函數
   
uninitialized_copy(b,e,b2)

從迭代器b和e指出的輸入范圍中拷貝元素到從迭代器b2開始的未構造的原始內存中,該函數在目的地構造元素,而不是給它們復制。

假定由b2指出的目的地足以保存輸入范圍中元素的副本

uninitialized_fill(b,e,t)  將由迭代器b和e指出的范圍中的對象初始化為t的副本,假定該范圍是未構造的原始內存,使用復制構造函數構造對象
uninitalized_fiil_n(b,e,t,n) 將由迭代器b和e指出的范圍中至多n個對象初始化為t的副本,假定范圍至少為n個元素大小,使用復制構造函數構造對象

      

      
    STL都會使用allocator類來為容器分配空間,例如:

#include <memory>

template <class T> class Vector {
    public:
        Vector(): elements(0), first_free(0), end(0) {}
        void push_back(const T&);

    private:
        static std::allocator<T> alloc; // object to get raw memory
        void reallocate();  // get more space and copy existing elements
        T* elements;        // pointer to first elment in the array
        T* first_free;      // pointer to first free element in the array
        T* end;             // pointer to one past the end of the array
};

template <class T> std::allocator<T> Vector<T>::alloc;

template <class T>
void Vector<T>::push_back(const T& t) {
    if (first_free == end) {
        reallocate(); 
    }   
    alloc.construct(first_free, t); 
    first_free++;
}

template <class T>
void Vector<T>::reallocate() {
    // compute size of current array and allocate space for twice as many elements
    std::ptrdiff_t size = first_free - elements;
    std::ptrdiff_t newcapacity = 2 * (size > 1 ? size : 1); 
    T* newelements = alloc.allocate(newcapacity);

    std::uninitialized_copy(elements, first_free, newelements);

    for (T* p = first_free; p != elements; alloc.destroy(--p));

    if (elements) {
        alloc.deallocate(elements, end - elements);
    }

    elements = newelements;
    first_free = elements + size;
    end = elements + newcapacity;
}

 

      

   

 

              

             

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM