序列容器vector和迭代器
一、容器vector
vector類模板提供了一種佔用連續記憶體地址的資料結構。這使得它可以高效,直接的利用下標運算子[]訪問vector中的任一元素,當一個vecto的記憶體空間耗盡時,它會分配一個更大的連續空間(陣列),把原先的資料複製(或移動)到新的空間(陣列),並把原來的空間(陣列)釋放。
其中的#0,#1…就是容器內的元素。從上圖可以看出vector維護的是一個連續的線性空間,和陣列是一樣的。所以不論其元素為何種型別,普通指標就可以作為vector的迭代器!因為vector迭代器所需要的操作如operator*,operator->,operator++,operator+,operator-,operator+=,operator-=,普通指標天生就具備。檢視vector的原始碼,我們可以看到vector的迭代器並沒有另外定義為一個模版類,而是直接 typedef value_type* iterator。 更可以看出 vector 的迭代器就是一個普通指標。
實現vector容器的類名為vector,包含類vector的標頭檔案是,並且名稱空間為std
二、迭代器Iterator
一個標準化遍歷各類容器裡面的所有物件的方法類(典型的設計模式),把訪問邏輯從不同型別的集合類中抽象出來,從而避免向客戶端暴露集合的內部結構
三、實現的功能
1.建立vector物件
定義了一個儲存Vector型別的物件iterator
typedef Iterator<Vector<T>> iterator; //類型別的重定義
用建構函式建立物件
Vector() { mdata = new T[2]; cursize = 0; totalsize = 2; }
2.vector物件不等關係的比較
bool operator!=(const Iterator<Container>& rhs)
{
return mpos != rhs.mpos;
}
3.使用指標輸出陣列
陣列中的指標可視為迭代器,函式begin返回指向陣列第一個元素的迭代器,函式end返回陣列末端最後一位的迭代器
//返回陣列第一個元素的迭代器 iterator begin() { return iterator(this, 0); } //返回陣列末端最後一位的迭代器 iterator end() { return iterator(this, cursize); }
4.使用運算子[]訪問和修改vector元素的下標
char& operator[](int index)
{
return mpstr[index];
}
5.一個vector物件用另外一個vector物件初始化
String(char* pstr) :mpstr(new char[strlen(pstr) + 1]())
{
strcpy(mpstr, pstr);
}
6.vector的成員函式 push_back:尾插入元素,如果在已滿的vector插入元素,vevtor會擴容
void push_back(T val)
{
if (IsFull())
{
resize();
}
mdata[cursize++] = val;
}
7.擴容
void resize()
{
T* pnewspace = new T[totalsize * 2];
memcpy(pnewspace, mdata, sizeof(T)*totalsize);
delete[]mdata;
mdata = pnewspace;
totalsize *= 2;
}
7.vector的成員函式 pop_back:尾刪除元素,若訪問一個無效的下標或無效的實參,丟擲異常 throw exception
void pop_back()
{
if (IsEmpty())
{
throw exception("vector is empty !");
}
cursize--;
}