我们可以把容器看作为一个小镇。
我们可以把迭代器看作为看作为一个房子,而值看作为房子里面的人。
序列式容器
顺序容器,在内存中是一块连续的内存,当插入、删除一个元素后,内存中的数据会发生移动,以保证数据的紧凑。所以删除一个数据后,其他数据的地址发生了变化,之前获取的迭代器根据原有的信息就访问不到正确的数据。
我们可以把容器看作为一个小镇。
迭代器看作为寻找某个人的地址,也就是房子的地址。这些房子必须是连在一起的。而房子越排在前面的人越强势。
1. 插入元素
当我们插入一个元素时,相当于新搬入一人。如果他比所有人都弱,我们只需要新建一座房子让他排在最后就行了。
但如果他是一个很强势的人。想搬到一个已经有房子的位置(位置3),于是他把别人家房子拆掉了,重新建了一座自己喜欢的房子。而以前这个位置的人也比后面的人强,于是他把位置4的房子拆了,新建了自己的房子。而位置4当然也去拆位置5的房子。。。。。。。。。。。
于是从搬入的位置开始后面所有的房子都变了样,如果我们按照以前的地址去寻找某个人的话就再也找不到了,于是我们更新了他们的位置,也就是插入位置开始,后面所有的迭代器都失效了都需要重新更新。
#include <iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
for (int i = 1; i < 10; i++) {
v.push_back(i);
}
auto end = v.end();
cout << *end << endl;
v.insert(v.begin(), 0); //插入后end迭代器失效
cout << *end << endl;
return 0;
}运行报错
2. 删除元素
当删除某个元素后,由于每个房子必须连在一起,所以后面的元素都需要向前移动位置,当移动之后所有的房子的位置也都发生了变化,删除的位置开始,所有的迭代器都失效了都需要重新更新。
删除容器中的3
int main()
{
vector<int> v;
for (int i = 1; i < 10; i++) {
v.push_back(i);
}
for (auto it = v.begin(); it < v.end(); it++)
{
if (*it == 3)
v.erase(it);
}
return 0;
}
运行报错
当删除it后 it失效,无法进行自增操作
解决方法
由于erase函数将返回下一个迭代器,所以我们可以通过接收返回值来更新迭代器
int main()
{
vector<int> v;
for (int i = 1; i < 10; i++) {
v.push_back(i);
}
for (auto it = v.begin(); it < v.end();)
{
if (*it == 3)
it = v.erase(it);
else
it++;
}
for (auto i : v)
cout << i << " ";
return 0;
}
3. 扩容
当搬进小镇的人越来越多,这个小镇的空间已经不够用了,于是小镇的所有居民都搬去了一个更大的小镇。于是他们的房子的位置都发生了改变。按照以前的地址再也找不到他们的位置了,于是我们又要进行迭代器的更新,于是所有的迭代器都需要重新更新。
int main()
{
vector<int> v;
for (int i = 1; i < 10; i++) {
v.push_back(i);
}
auto it = v.begin();
cout << *it << endl;
v.resize(20); //手动扩容 自动扩容也会导致迭代器失效
cout << *it << endl;
return 0;
}
京公网安备 11010502036488号