1. 程式人生 > >STL原始碼剖析(二)空間配置器

STL原始碼剖析(二)空間配置器

歡迎大家來訪二笙的小房子,一同學習分享生活!

文章目錄

1. 寫在前面

首先需要理解為什麼將空間配置器這一元件放在第二章進行講解?因為STL中的操作物件都存放在容器中,而容器需要空間配置器來配置空間,因此空間配置器作為STL中最重要的一個元件,理解了空間配置器對於後續容器的理解也會有很大的幫助。

2. SGI空間配置器

  • STL空間配置器標準介面一般由allocator類加上一些函式組成,而SGI STL的配置器更為與眾不同,其名稱使用alloc

2.1 SGI標準空間配置器

  • SGI定義了一個符合部分標準、名為allocator的配置器,但不建議使用,主要原因是效率不佳
  • 只把::operator new 和::operator delete簡單進行了包裝,部分程式碼如下:
//簡單封裝::operator new
template <typename T>
inline T* allocator(ptrdiff_t size,
T*) { set_new_handler(0); //關於該函式,具體可以在《effective C++》中條款49得以瞭解 T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); if (tmp == 0) { cerr << "out of memory" << endl; exit(1); } return tmp; } //簡單封裝::operator delete template <class T> inline void deallocate(T* buffer) { :
:operator delete(buffer); }

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

一般C++記憶體配置操作和釋放操作:

class  Foo { ... };
Foo* pf = new Foo;
delete pf;

new包含兩步操作:1.呼叫::operator new配置記憶體 2.呼叫建構函式構造物件內容
delete包含兩步操作:1.呼叫解構函式將物件析構 2.呼叫::operator delete釋放記憶體

  • STL將配置器定義於< memory>中,實現精密分工:
  1. #include <stl_construct.h>,定義了全域性函式construct()和destory(),負責物件的構造和析構
  2. #include <stl_alloc.h>,定義了一二級配置器,負責記憶體空間的配置和釋放
  • #include <stl_uninitialized.h>,定義了全域性函式,用來填充或複製大塊記憶體資料,該標頭檔案定義於memory,雖不屬於配置器,但與對像初值有關

2.3 構造和析構基本工具

定義在#include <stl_construct.h>中的construct()和destroy()

  • 物件構造:
template <class T1, class T2>
inline void construct(T1* p , const T2* value) {
  new (p) T1(value);    //呼叫T1::T1(value)
}
  • 物件析構:
//第一版本,接受一個指標
template <class T>
inline void destroy(T* pointer) {
    pointer->~T();   //呼叫析構
}
//第二版本,接受兩個迭代器,找出元素的數值型別,利用_type_traits<>選擇不同方式處理
template <class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardItertor last) {
   __destroy(first, last, value_type(first);  //呼叫該函式進行判斷
}
//如果判斷數值沒有那些影響效率的解構函式,則迴圈遍歷該範圍,並每經歷一個物件就呼叫第一個版本的destroy
template <class ForwardIterator>
inline void 
__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
     for (; first < last; ++first)
          destroy(&*first);   //對每一個物件呼叫一版本的destroy
}
//如果存在影響效率的解構函式,則什麼也不做
template <class ForwardIterator>
inline void 
__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {}

2.4 空間的配置與釋放

SGI STL空間配置與釋放解析

2.5 記憶體基本處理工具

  • 理解下圖所列的,我覺得大概就差不多了(忽略圖畫的不好看orz)