在本节中介绍**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()**的。
![](https://box.kancloud.cn/2016-03-09_56dfc9eca5e9b.jpg)
![](https://box.kancloud.cn/2016-03-09_56dfc9ecb9d33.jpg)
![](https://box.kancloud.cn/2016-03-09_56dfc9ecca2e4.jpg)
![](https://box.kancloud.cn/2016-03-09_56dfc9ecdaa17.jpg)
![](https://box.kancloud.cn/2016-03-09_56dfc9eceb979.jpg)
**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)