stl-vector详解
stl-vector詳解
stl-vector是應用最廣泛的一種容器,類似于array,都將數據存儲于連續空間中,支持隨機訪問。相對于array,vector對空間應用十分方便、高效,迭代器使vector更加靈活、安全。設計皆由vector起,鍵盤之下盡vector。
1 vector本質
??? vector數據結構如下,通過三個迭代器start, finish, end_of_storage的系列public接口,可很好地完成數據存儲、溢出判斷(iter >= iv.end())、大小、容量(容量與大小不等,以免不斷申請空間耗費資源)、重載操作符[]、判空、最前元素、最后元素等等。
class vector{…
protected:
iterator start ;
iterator finish;
iterator end_of_storage;
public:
iterator begin () { return start ; }
iterator end() { return finish; }
size_type size() const { return size_type( end() - begin()); }
size_type capacity() const { return size_type(end_of_storage - begin()); }
bool empty () const { return begin() == end(); }
reference operator[] (size_type n) { return *(begin() + n); }
reference front () { return *begin(); }
…
}
??? 由于vector是用連續空間存儲數據,不斷擴容將導致大量的新空間申請、元素拷貝和釋放原有空間,十分耗時,vector申請空間時,都將多申請部分空間備用,如下圖的[finish, end_of_storage)所示。只有當finish == end_of_storage時,再申請新的空間(2*capacity()), 圖2就是在圖1的基礎上,再插入元素引起的空間變化時的數據存儲情景。
圖1 vector數據存儲-1
??? 在圖1和圖2中的start不再指向相同的地址,擴大空間是新請新的更大的空間,因而不僅是start迭代器,其它指向空間變化前vector的迭代器都將失效。此處極易引起bug。
圖2 vector數據存儲-2
2 vector常用方法與技巧
1、空間申請
??? 構造函數、reserve()、resize()。
vector<int> iv(3, -1);iv.reserve(10);
iv.resize(10, -1); 構造函數不述;
???? reserve(n),申請空間,等同于擴大[finish, end_of_storage),當n <= capacity()時,無效,可以理解為主要改變end_of_storage(或capacity)——reserve()匹配capacity();
???? resize(10),申請空間并賦值,等同于改變[start, finish),可以理解為主要改變finish(或size())——resize()匹配size()。
2、空間釋放
??? erase()、resize()、clear()均僅改變finish(或size()),不改變end_of_storage。
??? swap()釋放空間——清空,改變end_of_storage:
vector<int> iv(10, -1);iv.reserve(500);
vector<int>().swap(iv);//交換空間
cout<<iv.capacity()<<endl;//輸出0
??? swap()釋放空間——釋放多余空間,改變end_of_storage:
vector<int> iv(10, -1);iv.reserve(500);
vector<int>(iv).swap(iv);//交換空間
cout<<iv.capacity()<<endl;//輸出10
3、resize()與operator []
??? operator []使得vector與array處理完全類似,但operator []極易引起異常與錯誤,如下:
vector<int> iv();iv.reserve(500);
iv[300] = -1;
cout<<iv.capacity()<<endl;//輸出500
cout<<iv.size()<<endl;//輸出0
這里就引起了迭代器不符合預期,也不知道什么才是預期。建議用法為resize()與operator []一起使用,從而使得操作完全等同于array,且安全: vector<int> iv();
iv.resize(500, 0);
iv[300] = -1;
cout<<iv.capacity()<<endl;//輸出500
cout<<iv.size()<<endl;//輸出500
4、vector迭代器
??? vector的迭代器十分簡單,等同于指針,++、--、+n、-n、>、<、!=等操作都可應用——random access iterator,基本上全部stl algorithms均可以在此上應用。
??? vector的插入操作,可能造成空間重新分配,使原有迭代器失效。
??? PS:強烈不推薦使用>,<,≤,≥之類比較迭代器,遍歷時直接使用!=即可,以免混于其它非random access iterator的容器。
總結
以上是生活随笔為你收集整理的stl-vector详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逻辑回归模型(Logistic Regr
- 下一篇: 特征值和特征向量(Eigenvalues