STL中vector是通常作为数组使用,不过它更像一个动态数组,在实际项目开发中大量使用.
优点:存储空间连续,可以使用下标访问,时间复杂度O(1).
缺点:不适合从中间删除和添加元素.
C++标准规定的vector模板声明:
template < class T, class Allocator = allocator<T> > class vector;
T : 存储的数据类型
Allocator : 存储空间分配器(默认为std::allocator<T>)
1)首先vector可以作为数组使用,因此我们可以在初始化vector时,指定元素个数和初始值.
vector<int> v; //v中含有0个元素
vector<int> v(5); //v中含有5个元素
vector<int> v(5, 1); //v中含有5个元素,赋予初始值1
另外vector还可以通过其他方式构造:
vector<int> third (v.begin(),v.end()); //通过v构造third
vector<int> fourth (third); //通过copy构造
//通过数组进行初始化
int myints[] = {16,2,77,29};
vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
这里暂且介绍这几种,更多构造方式查看C++手册.
2)其次我们要介绍下vector对内存的管理.
vector成员函数: size_type size() const;返回当前容器中元素个数
size_type capacity() const;返回当前容量大小(并不一定等于size())
vector为了减少内存频繁申请和释放capacity()返回的是当前容器实际申请内存空间所能容纳的元素个数,当我们在容器添加元素个数大于capacity()的大小时,容器将通过内存分配器重新分配空间(注: 一旦size()中的元素被移除掉, 被移除的对象对应的析构函数将会被调用.).
下面我们通过例子具体看看:
程序1:
vector<int> v;
for (size_t i = 0; i < 100; ++ i)
v.push_back(i);
cout << v.size() << endl;
cout << v.capacity() << endl;
输出:
100
141
可以看到size() 和 capacity()大小不一致.在vs中我们追踪push_back函数可以看到
Allocator : 存储空间分配器(默认为std::allocator<T>)
1)首先vector可以作为数组使用,因此我们可以在初始化vector时,指定元素个数和初始值.
vector<int> v; //v中含有0个元素
vector<int> v(5); //v中含有5个元素
vector<int> v(5, 1); //v中含有5个元素,赋予初始值1
另外vector还可以通过其他方式构造:
vector<int> third (v.begin(),v.end()); //通过v构造third
vector<int> fourth (third); //通过copy构造
//通过数组进行初始化
int myints[] = {16,2,77,29};
vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
这里暂且介绍这几种,更多构造方式查看C++手册.
2)其次我们要介绍下vector对内存的管理.
vector成员函数: size_type size() const;返回当前容器中元素个数
size_type capacity() const;返回当前容量大小(并不一定等于size())
vector为了减少内存频繁申请和释放capacity()返回的是当前容器实际申请内存空间所能容纳的元素个数,当我们在容器添加元素个数大于capacity()的大小时,容器将通过内存分配器重新分配空间(注: 一旦size()中的元素被移除掉, 被移除的对象对应的析构函数将会被调用.).
下面我们通过例子具体看看:
程序1:
vector<int> v;
for (size_t i = 0; i < 100; ++ i)
v.push_back(i);
cout << v.size() << endl;
cout << v.capacity() << endl;
输出:
100
141
可以看到size() 和 capacity()大小不一致.在vs中我们追踪push_back函数可以看到
![](https://images0.cnblogs.com/blog/339657/201310/07210132-48c1e2021f4048fcb3ef096f4c3fc679.png)
首先比较size()和capacity()大小,如果容器容量足够容纳元素则直接添加至尾部,否则我们进入insert函数继续追踪,
![](https://images0.cnblogs.com/blog/339657/201310/07210219-2bbdb0376958402e8798d591b639c6f3.png)
进入_Insert_n中,我们看到一旦新添加元素数量和当前实际使用元素数量大于capacity()后,则容器容量尝试以50%的容量增长.
![](https://images0.cnblogs.com/blog/339657/201310/07210235-68946998b8944c22bfc56c938db3bc67.png)
vector的成员函数: void resize ( size_type sz, T c = T() );改变实际元素个数.
1.如果_Newsize小于size(),则容器将截断后面(size() - _Newsize)个元素, 保留前面的元素;
2.如果_Newsize大于size(),则容器将调用_Insert_n函数进行插入操作,只有(_Newsize - size())的元素才使用初始化值进行初始化,原来的size()个元素保持不变.
vector成员函数: void reserve ( size_type n );改变容器容量大小.
1.如果n小于capacity()大小,则容器并不会进行释放内存重新分配,此操作无效.
2.如果n大于capacity()大小,则容器重新分配内存,并将原来元素copy进新的内存中.
程序2:
vector<int > v;
for (size_t i = 0; i < 100; ++ i )
v.push_back (i);
v.reserve (10);
cout << v .size() << endl;
cout << v .capacity() << endl;
输出:
100
141
141
程序3:
vector<int > v;
for (size_t i = 0; i < 100; ++ i )
v.push_back (i);
v.reserve (150);
cout << v .size() << endl;
cout << v .capacity() << endl;
输出:
100
150
vector的clear()操作并不会造成内存的释放,只是改变实际元素个数置为0;而iterator erase ( iterator position );操作也只是对元素进行移动操作,并不会释放内存.
总结:我们在使用vector时最好事先分配一定的数量的元素空间,删除和添加最好在尾部操作.