向量vector
1.vector概述
vector的資料安排以及操作方式,與array非常相似。兩者的唯一差別在於空間的運用的靈活性。array是靜態空間,一旦配置了就不能改變;vector是動態空間,隨著元素的加入,它的內部機制會自行擴充空間以容納新元素。
vector的實現技術,關鍵在於其對大小的控制以及重新配置時的資料移動效率。一旦vector舊有空間滿載,如果客戶每新增乙個元素,vector內部只是擴充乙個元素的空間,實為不智,因為所謂擴充空間(不論多大),一如稍早說,是「配置新空間 / 資料移動 / 釋還舊空間」的大工程,時間成本很高,應該加入某種未雨綢繆的考慮。稍後我們便可以看到sgi vector的空間配置策略。
2.定義:
以下是vetor定義的源**摘錄。雖然stl規定,欲使用vector必須先包括,但sgi stl將vector實現吾更底層的
3.vector的迭代器vector維護的是乙個連續線性空間,所以不論其元素型別為何,普通指標都可以作為vector的迭代器而滿足所有必要條件,因為vector迭代器所需要的操作行為,如operator*,operator->operator++,operator--,operator+,operator-,operator+=,operator-=,普通指標天生就具備。vector支援隨機訪問,而普通指標正有著這樣的能力。所以,vector提供的是random access itrerators。// alloc是sgi stl的空間配置器
template class vector
void fill_initialize(size_type n, const t& value)
public:
iterator begin()
iterator end()
size_type size() const
size_type capacity() const
bool empty() const
reference operator(size_type n)
vector() : start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const t& value)
vector(int n, const t& value)
vector(long n, const t& value)
explicit vector(size_type n)
~vector()
destroy(start, finish); // 全域性函式
deallocate(); // 這是 vector 的乙個 member function
}reference front() // 第乙個元素
reference back() // 最後乙個元素
void push_back(const t& x)
else
insert_aux(end(), x); // 這是 vector 的乙個 member function
}void pop_back()
iterator erase(iterator position)
void resize(size_type new_size, const t& x)
void resize(size_type new_size)
void clear()
protected:
// 配置空間並填滿內容
iterator allocate_and_fill(size_type n, const t& x)
template class vector ;
根據上術定義,如果客戶端寫出這樣的**:
ivite的型別其實就是int*,svite的類別其實就是shape*。vector::iterator ivite;
vector::iterator svite;
4.vector的資料結構
vector所採用的資料結構非常簡單:線性連續空間。它以兩個迭代器start和finish分別指向配置得來的連續空間中目前已被使用的範圍,並以迭代器end_of_storage指向整塊連續空間(含備用空間)的尾端:
template class vector ;
為了降低空間配置時的速度成本,vector實際配置的大小可能比客戶需求量更大一些,以備將來可能擴充。這便是容量(capacity)的觀念。換名話說,乙個vector的容量永遠大於或等於其大小。一旦容量等於大小,便是滿載,下次再有新增元素,整個vector就得另覓居所,見下圖。
運用start,finish,end_of_storage三個迭代器,便可輕易地提供首尾標示、大小、容量、空容器判斷、注標([ ])運運算元、最前端元素值、最後端元素值...等機能;
5.vector的構造與管理:constructor,push_back
千頭萬緒該如何說起?以客戶端 程式**為引導,觀察其所得結果並實證原**,是乙個良好的學習路徑。不面是乙個小小的測試程式,觀察重點在構造的方式、元素的新增,以及大小、容量的變化:
於是,data_allocator::allocatore(n)表示配置n個元素空間。// filename : 4vector-test.cpp
#include #include #include using namespace std;
int main()
;
vector提供許多constructors,其中乙個允許我們指定空間大小及初值:
uninitialized_fill_n()會根據第一引數的型別特性(type traits)決定使用演算法fill_n()或反覆呼叫construct()來完成任務。// 建構函式,允許指定 vector 大小 n 和初值 value
vector(size_type n, const t& value)
// 充填並予以初始化
void fill_initialize(size_type n, const t& value)
// 配置而後填充
iterator allocate_and_fill(size_type n, const t& x)
當我們以push_back()將元素插入於vector尾端時,該函式產生檢查是否還有備用空間,如果有就直接在備用空間上構造元素,並調整迭代器finish,使vector變大。如果沒有備用空間了,就擴大空間(重新配置、移動資料、釋放空間):
template class vector ;
於是,data_allocator::allocate(n) 表示配置n 個元素空間。
vector 提供許多 constructors,其中乙個允許我們指定空間大小及初值:
注意,所謂動態增加大小,並不是在原空間之後接續新的空間(因為無法保證原空間之後尚有可供配置的空間),而是以原大小的兩倍另外配置一塊較大的空間,然後將原內容拷貝過來,然後才開始在原內容之後構造新元素,並釋放原空間。因此,對vector的任何操作,一旦引起空間重新配置,指向原vector的所有迭代器就都失效了。這是程式設計師易犯的乙個錯誤,務需小心。// 建構函式,允許指定 vector 大小 n 和初值 value
vector(size_type n, const t& value)
// 充填並予以初始化
void fill_initialize(size_type n, const t& value)
// 配置而後填充
iterator allocate_and_fill(size_type n, const t& x)
void push_back(const t& x)
else // 已無備用空間
insert_aux(end(), x); // vector member function,見以下列表
}template void vector::insert_aux(iterator position, const t& x)
else
catch (...)
// 析構並釋放原 vector
destroy(begin(), end());
deallocate();
// 調整迭代器,指向新vector
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}}
stl原始碼剖析之vector
作者最近在學習c 學習侯捷的stl原始碼剖析這本書,但是我覺得裡面的內容有些古老並且生澀。比如說alloc,對於一些基礎知識不太牢固的同學不是很友好 我建議先細讀第二章前4小節,第一級分配器之後的內容可等基礎足夠再回頭彌補 雖然這本書本就不是面對像菜鳥的c 程式設計師。然一些基礎思想,程式設計方法,...
STL原始碼剖析 一 vector
開始學習 stl原始碼剖析 已經學習了前兩章 有關記憶體管理 以及 迭代器 下面 先嘗試自己寫vector再根據源 進行 修改 以下為 ifndef vector h define vector h include alloc.h define vector overflow std cerr ve...
STL原始碼剖析 容器 vector
vector 常被稱為向量容器,因為該容器擅長在尾部插入或刪除元素,在常量時間內就可以完成,時間複雜度為o 1 而對於在容器頭部或者中部插入或刪除元素,則花費時間要長一些 移動元素需要耗費時間 時間複雜度為線性階o n vector實現的關鍵在於其對大小的控制以及重新配置時的資料移動效率。vecto...