在本節中介紹**STL**標準庫類型的**vector**容器。容器(**container**),顧名思義表示對象的集合,這些對象的類型都相同,每個對象都有一個自己的索引,用這個索引我們就可以方便的訪問該對象了。
實際上,**STL**中的**vector**容器就是動態大小數組。我們先來看看**vector**的一些操作,最后再做一個實例。首先,要使用**vector**,需要包含頭文件,以及做**using**申明。
~~~
#include <vector> //頭文件包含
using namespace std; //或者using std::vector;
~~~
其次,再看**vector**的定義和初始化,這里以**int**類型舉例。
~~~
vector<int>v1; //空的vector,元素類型為int,執行的是默認初始化
vector<int>v2(v1); //拷貝覆蓋,v2與v1中元素個數、值都相同
vector<int>v3=v1; //同上
vector<int>v4(5,3); //v4包含了5個重復元素,元素值為3
vector<int>v5(10); //v5包含10個重復元素,執行的是默認初始化
//列表初始化,是C++11提供的新標準
vector<int>v6{1,2,3,4}; //v6包含4個元素,其值為{...}中的元素
vector<int>v7={1,2,3,4}; //同上
~~~
了解了一些基礎知識后,我們來看看**vector**有哪些常用的操作方法。
**vector的member functions**
| push_back() | 在容器尾部添加元素 | crbegin() | ? |
|-----|-----|-----|-----|
| pop_back() | 刪除容器的最后一個元素 | crend() | ? |
| size() | 返回容器中實際元素的個數 | clear() | 清除容器中所有元素 |
| resize() | 重新設定容器的大小 | capacity() | 返回需要重新分配容量的元素個數 |
| at() | 返回索引位置的元素 | reserve() | 設定重新分配容量的元素個數 |
| begin() | 返回第一個元素的迭代器 | data() | ? |
| end() | 返回最后一個元素后面位置的迭代器 | assign() | 賦值 |
| front() | 返回第一個元素 | insert() | 插入 |
| back() | 返回最后一個元素 | max_size() | 返回最大數據量 |
| empty() | 返回1為空,0為非空 | get_allocator() | 使用構造函數,返回一個拷貝 |
| swap() | 交換兩容器 | shrink_to_fit() | ? |
| cbegin() | ? | emplace_back() | ? |
| cend() | ? | erase() | 擦除元素 |
| rbegin() | 返回逆向容器中的第一個元素的迭代器 | emplace() | ? |
| rend() | 返回逆向容器中的最后一個元素后面位置的迭代器 | ? | ? |
接下來,對**vector**的成員方法進行逐一闡述:
~~~
vector<int>c; //定義vector容器c,數據類型為int
~~~
**1、push_back(val)**
將元素val添加到容器尾部,同時c.size()會增加。
~~~
c.push_back(val);
~~~
需要說明的是:**c.push_back(val)**先將容器c中的元素拷貝到新的內存空間中,然后在將**val**值拷貝到新空間的末尾,最后析構掉原始空間。當**push_back**檢測到空間不足時,將自動以**2**倍的方式擴展空間。對于大量數據來說,這是一個弊端,可以使用**vector::reserve**方法來改善。
其定義如下,調用的方法**vector::insert**,在容器尾部**insert**來實現的。
~~~
void push_back(_Elem _Ch)
{ // insert element at end
insert(end(), _Ch);
}
~~~
**2、pop_back()**
刪除容器尾部元素,同時**c.size()**會減少。
~~~
c.pop_back(); //刪除尾部元素
~~~
其定義如下,調用的方法**vector::earse**,擦除最后一個位置元素來實現的。
~~~
void pop_back()
{ // erase element at end
erase(this->_Mysize - 1); // throws if _Mysize == 0
}
~~~
**3、size()**
容器實際大小,返回容器中元素的個數。
~~~
c.size();
~~~
其定義如下:
~~~
size_type size() const
{ // return length of sequence
return (this->_Mysize);
}
~~~
**4、resize()**
重新設定容器大小,**c.size()**會發生改變。
~~~
//c.size()<n時,擴大容器,多余的元素追加在末尾,執行默認初始化;反之,則將容器截斷,保留前面n個元素
c.reize(n);
//c.size()<n時,擴大容器,多余的元素追加在末尾,其值都為val;反之,則將容器截斷,保留前面n個元素
c.resize(n,val);
~~~
注意:**resize()**改變了容器大小,且創建了對象,可以使用操作符operator[]或迭代器進行元素的訪問。
**5、at()**
訪問某個位置元素,返回元素值。
~~~
c.at(index); //返回index處的元素值
~~~
注意:**index**的范圍在**[0,c.size()]**之間,**at()**方法,對索引有越界判斷,若**index**越界,則會拋出**out_of_range**異常。
**6、begin()**
返回容器第一個元素的迭代器。(迭代器可理解為指針的加強版)
~~~
vector<int>::iterator it = c.begin();
~~~
**7、end()**
返回容器末尾元素后面位置的迭代器。
~~~
vector<int>::iterator it = c.end();
~~~
**8、front()**
返回容器的第一個元素。
~~~
c.front()
~~~
其定義如下:
~~~
reference front()
{ // return first element of mutable sequence
return (*begin());
}
~~~
**9、back()**
返回容器的最后一個元素。
~~~
c.back()
~~~
其定義如下:
~~~
reference back()
{ // return last element of mutable sequence
return (*(end() - 1));
}
~~~
**10、empty()**
判斷容器是否為空。返回**0**表示非空,返回**1**表示空。
~~~
c.empty()
~~~
**11、swap()**
兩容器相互交換,對象類型必須相同才能交換。
~~~
vector<int>c(5,1); //5個元素,值均為1
vector<nt>a(10,2); //10個元素,值均為2
c.swap(a); //交換兩容器,下同
swap(c,a);
swap(a,c);
~~~
經過一次交換后,**a**容器有**10**個元素,值均為**2**;**c**容器有**5**個元素,值均為**1**。
**12、cbegin()**
同**begin()**,返回的是**const**類型的迭代器。
其定義如下:
~~~
const_iterator cbegin() const
{ // return iterator for beginning of nonmutable sequence
return (((const _Myt *)this)->begin());
}
~~~
**13、cend()**
同**end()**,返回的是**const**類型的迭代器。
~~~
const_iterator cend() const
{ // return iterator for end of nonmutable sequence
return (((const _Myt *)this)->end());
}
~~~
**14、rbegin()**
返回逆向容器中第一個元素的迭代器。
~~~
vector<int>::reverse_iterator it = rbegin();//++it則表示正向的倒數第二個元素的迭代器
~~~
注:實際上,是正向的最后一個元素后面位置的迭代器。
**15、rend()**
返回逆向容器中最后一個元素后面位置的迭代器。
~~~
vector<int>::reverse_iterator it = rend();
~~~
注:實際上,是正向第一個元素的迭代器。
**16、crbegin()**
同**cbegin()**,只不過是逆向的。
~~~
c.crbegin();
~~~
**17、crend()**
同**crbegin()**;
~~~
c.crend();
~~~
**18、clear()**
清除容器中所有元素,被還原成一個空的容器。
~~~
c.clear();
~~~
**19、capacity()**
返回需要重新分配容量的元素個數。
~~~
c.capacity();
~~~
注:不一定是按2的指數增長的哦,下面是我在**xp vs2010**上測試得到的值。且**c.capacity()**至少是**大于等于****c.size()**的。

?
?
?
?
**20、reserve()**
~~~
c.reserve(length);
~~~
注意:若**length<=c.capacity()**,則不會發生任何改變;因此**length>c.capacity()**才有意義。
**21、data()**
**22、assign()**
賦值,相當于將容器**c**中的所有元素的清除,然后重新生成一個**n**個元素值均為**val**的容器。**c.size()**為**n**。
~~~
c.assign(n,val);
~~~
**23、insert()**
在某個位置插入或連續插入元素。
~~~
//在第一個位置插入一個元素
c.insert(c.begin(), val);
//從第二個位置開始,連續插入兩個元素
c.insert(c.begin()+1, 2, vla);
//從第三個位置開始,連續插入第一個位置到最后一個位置之間的元素
c.insert(c.begin()+2, c.begin(), c.end() - 1);
~~~
**24、max_size()**
返回容器最多能容納元素的個數。數據類型所占字節相同的容器,其返回值相同。如**vector<int>a**、**vector<float>b**,容器**a**與**b**的**max_size**就相同。
~~~
c.max_size();
~~~
**25、get_allocator()**
**26、shrink_to_fit()**
**27、emplace_back()**
**28、emplace()**
**29、erase()**
擦除某個位置或某個連續位置的元素。**c.size()**發生改變,**c.capacity()**不會發生改變。
~~~
//擦除倒數第二個元素
c.erase(c.end() - 2);
//擦除第二個元素到最后一個元素之間的所有元素(閉集合,包含本身)
c.erase(c.begin() + 1, c.end() - 1);
~~~
未完待續。。。
**參考:**
**[https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx](https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx)**
[**https://msdn.microsoft.com/zh-cn/cn-us/library/9xd04bzs.aspx**](https://msdn.microsoft.com/zh-cn/cn-us/library/9xd04bzs.aspx)