vector,直译为向量,我们一般称为动态数组,一般不去翻译,直接使用vector称呼。它是STL诸多数据结构中使用最广泛的几个数据结构之一。C++编程规范中指出,如果你不知道使用哪个容器合适,就使用vector吧。无论从使用的方便程度和效率上,都可圈可点。下面详细学习该数据结构,以C++11为准。
构造函数:
类别 | 声明 |
---|---|
default (1) | explicit vector (const allocator_type& alloc = allocator_type()); |
fill (2) | explicit vector (size_type n); vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type()); |
range (3) | template vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); |
copy (4) | vector (const vector& x); vector (const vector& x, const allocator_type& alloc); |
move (5) | vector (vector&& x); vector (vector&& x, const allocator_type& alloc); |
initializer list (6) | vector (initializer_list |
默认构造
std::vector<T> vec; // 创建一个元素类型为T的空数组
填充构造
std::vector<T> vec(1); // 创建一个元素类型为T的数组,数组大小为1,元素内容为0
std::vecotr<T> vec(1, 2); // 创建一个元素类型为T的数组,数组大小为1,元素内容为2
bool empty() const noexcept;
查看vector是否为空,size 为 0,则为true。建议使用该函数来查看vector是否为,而不是比较size() == 0.
size_type size() const noexcept;
size_type capacity() const noexcept;
size和capacity的关系如下:
+---+---+---+---+---+----------+
| 0 | 1 | 2 |...| 23| reserved |
+---+---+---+---+---+----------+
| |
size() capacity()
size是指vector已经保存的元素的数目;而capacity则是在不分配新的内存空间的前提下它最多可以保存多少元素。
reference front();
const_reference front() const;
reference back();
const_reference back() const;
reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
reference at (size_type n);
const_reference at (size_type n) const;
访问元素的方式,可以通过front(),back(),下标和at()几种成员函数。它们返回的均是引用,如果vector是一个const对象,则返回值是const的引用。对于非const引用,我们可以通过该返回值,来修改容器中该元素的值。
void push_back (const value_type& val);
void push_back (value_type&& val);
通过成员函数push_back往vector的末尾添加元素,这个效率是非常高的。
// 往vector末尾依次添加两个元素
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
template <class... Args>
void emplace_back (Args&&... args);
在C++11增加了新的成员函数,用于在vector末尾插入数据。
// 往vector末尾依次添加两个元素
std::vector<int> vec;
vec.emplace_back(1);
vec.emplace_back(2);
和push_back的区别在于,如果vector的元素是一个对象时,push_back接受的是一个对象,而emplace_back接受的是构造这个对象的参数。
class A {
public:
A(int arg){}
... ...
}
// 使用push_back存储
std::vector<A> vec;
A a(1);
vec.push_back(a);
// 使用emplace_back存储
std::vector<A> vec;
vec.emplace_back(1);
其他类似功能成员函数
vector除了上面介绍的两种添加元素的成员函数,还有insert,push_front, emplace等。但,插入vector末尾是最高效的,上面的两种函数使用最广泛。不要贪多,容易混乱。
拷贝
需要注意的是,往vector中添加元素时,添加的是拷贝,不是本尊。如上面的例子中的a对象,存储到vector时,存储的是a对象的拷贝,不是a自身。
指针
在vector中存储指针时需要注意,vector管理的是指针自身,并不负责指针指向的内容。在销毁vector或删除元素时,需要自己提前处理该指针对应的内存。比较好的解决方案是使用智能指针。
void pop_back();
前面介绍的push_back用于在vector的末尾添加元素,与之对应的pop_back则是从vector的末尾删除元素。
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
// 从末尾删除一个元素
vec.pop_back();
// 此时vec中只有1这一个元素了
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
删除迭代器指定的元素,获取迭代器指定范围内的元素。返回一个指向被删除元素之后元素的迭代器。
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
// 删除vector中元素为奇数的元素
std::vector<int>::iterator it = vec.begin();
while (it != vec.end()) {
if (*it % 2) {
it = vec.erase(it);
} else {
++it;
}
}
// 此时vec中只有2这一个元素了
注意:
void clear() noexcept;
删除vector的所有元素,即清空vector。vector的size为0,但是,capacity并不没有变化,即之前的为所有元素申请的内存并未释放。
释放的经典方式为:
std::vector<T>().swap(x); // clear x reallocating
// 举例
std::vector<int> vec(4, 1); // 创建一个拥有4个元素的vector,此时vector的size: 4, capacity: 4
vec.clear(); // 此时vector的size: 0, capacity: 4
std::vector<int>().swap(vec); // 此时vector的size: 0, capacity: 0,之前存储元素所有的内存成功释放
原理是:
创建一个相同类型的临时变量,std::vector
临时变量和带操作变量即vec交换
交换后,临时变量管理vec的内存,vec管理临时变量的内存,临时变量是空的vector,所以,交换后的vec也就是空vector了
临时变量销毁
因为是临时变量,在当前行代码执行完后,临时变量就销毁。随着销毁的还有它管理的之前vec的内存。
通过上面的三步,vec的多余内存得以释放。C++11增加了成员函数shrink_to_fit
,用于解决退还内存的问题。但是,调用shrink_to_fit
只是一个请求,标准库并不保证退还内存。
void reserve (size_type n);
reserve用来通知容器应该准备保存多少个元素。它改变的是capacity的大小。只有当需要的内存空间超过当前容量时,reserve调用才会改变vector的容量。
如果事先知道自己大约需要保存多少个元素,可以调用该成员函数,事先申请内存,这样不至于随着元素的增加,标准库内部反复重新申请和释放内存。
void resize (size_type n);
void resize (size_type n, const value_type& val);
resize用来增大或缩写容器,它改变的是size的大小。如果当前大小大于所要求的大小,则容器后部的元素会被删除;如果当前大小小于新大小,会将新元素添加到容器后部;
std::vector<int> vec(3, 1); // 创建一个vector,包含3个元素,初始化值均为1,内容为:1 1 1
vec.resize(4); // 调整vector元素为4个,最新增加的一个元素为0,内容为:1 1 1 0
vec.resize(8, 2); // 调整vector元素为8个,最新增加的4个元素为2,内容为:1 1 1 0 2 2 2 2
vec.resize(6); // 调整vector元素为8个,删除后面多余的两个元素,内容为:1 1 1 0 2 2
http://www.cplusplus.com/reference/vector/vector/
C++ primer 第五版