stl空間配置器簡介

  一、 符合STL標準的空間配器接口c++

STL是c++中使用很是普遍的一個標準庫,它包含各類有用的容器。而空間配置器做爲STL各類容器的背後的核心,負責容器內部內存的分配和釋放。不過空間配置器能夠分配的也不僅是內存,由於空間也意味着能夠是磁盤或者其餘存儲介質。下邊是一個符合STL規範的空間配置器的必要接口:函數

allocator::value_type工具

allocator::pointer指針

allocator::const_pointer對象

allocator::reference接口

allocator::const_reference內存

allocator::size_typeast

allocator::difference_typeclass

//上邊這幾個都是一些typedef定義,其中 size_type 和difference_type是stddef.h中 size_t, ptrdiff_t這兩個類型的類型別名(ptrdiff_t是兩個指針相減的結果)效率

allocator::rebind

allocator::allocator

allocator::allocator(const allocator&)

template<class U>

allocator::allocator(const allocator(U)&)

//泛化的拷貝構造函數

allocator::~allocator()

pointer allocator::address(reference X) const

const_pointer allocator::address(const_reference X)const

pointer allocator::allocator(size_type n, const void* = 0)

void allocator::deallocate(pointer p, size_type n)

//歸還先前配置的空間

size_type allocator::max_size() const

void allocator::construct(pointer p, const T& x)

void allocator::destrory(pointer p)

 

二、 SGI空間配置器

SGI STL的配置器與標準規範不一樣,其名稱是alloc而不是allocator,並且不接受任何參數。若是在程序中須要明確使用SGI的配置器,咱們不能採用標準寫法:

vector<int, std::allocator<int> > v

須要這麼寫:

vector<int, std::alloc> v

一般狀況下,咱們使用的stl中的容器都是用標準配置器,而SGI STL的每個容器都已經指定其缺省空間配置器爲alloc,如:

 

template <class T, class Alloc=alloc>

class vector {…}

 

2.1 標準空間配置器

SGI STL也有一個符合標準,名爲allocator的配置器,但SGI從未使用過它,由於它效率過低,只是對::operator new, ::operator delete的簡單封裝而已;下邊我着重介紹SGI特殊的配置器alloc。

 

2.2 SGI特殊空間配置器, std::alloc

C++中,咱們在申請內存和釋放內存的時候,通常這樣作:

class Foo{}

Foo* f = new Foo

delete f

這其中new操做符內部含有兩階段操做,(1)調用new申請內存, (2)調用Foo:Foo()即對象的構造函數構造對象內容。

delete也含有兩段操做:(1)調用Foo::~Foo()將對象析構, (2) 調用delete 釋放內存。

爲了精密分工也更有效的利用內存,SGI alloc將這兩個階段分開來操做。內存配置有alloc::allocator()負責內存配置,alloc::deallocator()負責內存釋放;::constructor()負責構造對象;::destrory負責析構對象。

 

2.3內存配置後對象的構造與內存釋放前對象的析構工具: constructor()和destrory()

這兩個函數爲全局函數,符合stl規範。

constructor()接受一個指針p和一個初值,該函數的做用是將初值設定到指針所指的內存空間上

template<class T1, class T1>

inlie void destructor(T1 *p, const T2 &value) {

new (p) T1(value) //placement new 在一個已經分配的內存中建立對象

}

destroy()函數有兩個版本,一個版本接受一個指針參數,直接調用這個指針所指對象的析構函數析構對象。

template<class T>

inline void destroy(T* pointer){

pointer->~T();

}

另一個版本接受兩個迭代器,

template<class ForwardIterator, class T>

inline void destroy(ForwardIterator first, ForwardIterator last, T*) {

}

destroy函數實現的有點複雜,他先獲取到迭代器所指對象的的類型,而後在看對象是否有trivial destructor, 若是有,調用一個什麼也不作的版本;若是有non-trivial destructor,則遍歷迭代器中的每個對象,而後依次調用其析構函數。

(這裏主要是處於效率考慮, 若是一個對象的析構函數沒有任何做用,那麼循環調用這個函數對效率是一種傷害)。

備註:

        什麼是trivial destructor呢?舉個例子來講,存在A,B兩個類,其中類B含有一個數據成員C,C有析構函數須要釋放一些內存;那麼在這種狀況下,A就含有trivial destructor, 而B則含有non-trivial destructor。

相關文章
相關標籤/搜索