vector的使用
vector的定义
构造函数声明 | 接口说明 |
---|---|
vector()(重点) | 无参构造 |
vector(size_type n, const value_type& val = value_type()) | 构造并初始化n个val |
vector (const vector& x); (重点) | 拷贝构造 |
vector (InputIterator first, InputIterator last); | 使用迭代器进行初始化构造 |
vector iterator 的使用
iterator的使用 | 接口说明 |
---|---|
begin+end | end(重点)获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置 的iterator/const_iterator |
rbegin+rend | 获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的 reverse_iterator |
vector空间增长问题
容量空间 | 接口说明 |
---|---|
size | 获取数据个数 |
capacity | 获取容量大小 |
empty | 判断是否为空 |
resize | 改变vector的size |
reserve | 改变vector放入capacity |
- capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。vs是PJ版本STL,g++是SGI版本STL。
- reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
- resize在开空间的同时还会进行初始化,影响size
vector增删查改
vector增删查改 | 接口说明 |
---|---|
push back | 尾插 |
pop back | 尾删 |
find | 查找 (注意这个是算法模块实现,不是vector的成员接口) |
insert | 在position之前插入val |
erase | 删除position位置的数据 |
swap | 交换两个vector的数据空间 |
operator[] | 像数组一样访问 |
operator[]+index 和 C++11中vector的新式for+auto的遍历
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
for(auto x : v)
cout<< x << " ";
交换两个vector的数据空间
vector<int> swapv;
swapv.swap(v); //交换了v和swapv的数据空间
vector 迭代器失效问题(重点)
迭代器失效场景总结:
- 删除pos迭代器位置所指向元素没有及时给pos赋值,比如v.erase(pos)
- 可能会引起vector底层空间改变的操作,比如:push_back、insert、resize、reserve等
- 同样的原因也会导致引用失效。因为引用和迭代器本质都是指针!!!
例如:int a[] = { 1, 2, 3, 4 }; vector<int> v(a, a + sizeof(a) / sizeof(int)); int &num=v[0]; v.push_back(1); num=100;//这时会出现错误,原因类似。
- earse函数并不会真正的判断底层删除的该块内存是否真的失效了,例如删除第一个元素内存块并不会失效,因为后面的元素整体向前移动了。但是在STL底层系统默认了只要调用erase函数都会导致迭代器失效,这样减少了判断是否失效了那部分代码,减低了代码的复杂度!!!
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(int));
// 使用find查找3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
// 删除pos位置的数据,导致pos迭代器失效。
v.erase(pos); //正确使用 pos = v.erase(pos);
cout << *pos << endl; // 此处会导致非法访问
// 在pos位置插入数据,导致pos迭代器失效。
// insert会导致迭代器失效,是因为insert可能会导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了。
pos = find(v.begin(), v.end(), 3);
v.insert(pos, 30); //正确使用 pos = v.insert(pos,30);
cout << *pos << endl; // 此处会导致非法访问