1. 迭代器简介
迭代器是一种遍历容器内元素的数据类型。这种数据类型类似指针,可以理解为迭代器用来指向容器中的某个元素。
2. 迭代器的定义
int main() {
vector<int> v1{1, 2, 3, 4, 5};
//将vector<int>::iterator理解成一个类型,利用这种类型定义的变量iter即为迭代器
vector<int>::iterator iter;
}
3.迭代器的使用
3.1 begin()/end()操作
(1) v.begin():若容器中有元素,则返回一个迭代器,其指向容器中第一个元素。
(2)v.end():返回容器中最后一个元素的下一个位置,即指向一个不存在的元素。
(3)若一个容器为空,则v.begin()与v.end()返回的是同一个迭代器。
int main() {
vector<int> v1{1, 2, 3, 4, 5};
vector<int>::iterator begin = v1.begin();//返回指向第一个元素的迭代器
vector<int>::iterator end = v1.end();//返回指向最后一个元素下一个位置的迭代器
cout << *begin << endl; //1
cout << *end << endl; //错误
}
int main() {
vector<int> v1; //空容器
vector<int>::iterator begin = v1.begin();//返回指向第一个元素的迭代器
vector<int>::iterator end = v1.end();//返回指向最后一个元素下一个位置的迭代器
if (begin == end)
{
cout << "容器为空" << endl;
}
}
3.2 rbegin()/rend()操作
反向迭代器:从后往前遍历一个容器
v.rbegin():返回一个反向迭代器,指向反向迭代器的第一个元素
v.rend():返回一个反向迭代器,指向反向迭代器的最后元素的下一个位置。
int main() {
vector<int> v1{1, 2, 3, 4}; //空容器
for(vector<int>::reverse_iterator riter = v1.rbegin(); riter != v1.rend(); riter++)
{
cout << *riter << endl; //4,3,2,1
}
}
3.3 iter++ / iter–操作
iter++,++iter:让迭代器指向容器的下一个元素,若已在容器最后则不能再++
iter–,--iter:让迭代器指向容器的上一个元素,若已在容器开头则不能再–
int main() {
vector<int> v1{1, 2, 3, 4, 5};
vector<int>::iterator begin = v1.begin();//返回指向第一个元素的迭代器
vector<int>::iterator end = v1.end();//返回指向最后一个元素下一个位置的迭代器
cout << *(++begin) << endl; //让迭代器指向begin的下一个元素, 2
cout << *(--end) << endl; //让迭代器指向end的上一个元素, 5
}
3.4 访问容器中自定义类型的成员
int main() {
//定义一个存放Person类型对象的容器
vector<Person> vp;
//定义Person类型的对象
Person p1;
p1.m_Name = "aolaf";
//将Person类型对象放入容器
vp.push_back(p1);
//定义Person容器的迭代器
vector<Person>::iterator begin = vp.begin();
cout << (*begin).m_Name << endl; //*begin为迭代器指向的容器中第一个Person类型对象
cout << begin->m_Name << endl;
}
3.5 const_iterator迭代器
const_iterator迭代器指向的元素值不可改变,但可以移动该迭代器
int main() {
vector<int> v1{1, 2, 3};
vector<int>::const_iterator iter = v1.begin();
iter ++;
cout << (*iter) << endl; //2, const_iterator型迭代器可以移动
// (*iter) = 5; //错误,const_iterator型迭代器指向的元素值无法被更改
}
3.6 cbegin()/cend()
cbegin()和cend()返回的是常量迭代器,其指向的元素值无法被更改
int main() {
vector<int> v1{1, 2, 3};
auto iter = v1.cbegin(); //cbegin()返回const_iterator型迭代器
iter ++;
cout << (*iter) << endl; //2, const_iterator型迭代器可以移动
// (*iter) = 5; //错误,const_iterator型迭代器指向的元素值无法被更改
}
4. 迭代器失效
4.1 迭代器失效情况
若使用迭代器循环遍历容器,千万不要在循环内部改变容器的容量(不要增加或删除容器的元素)。
错误代码:
int main() {
vector<int> v1{1, 2, 3};
for (auto iter = v1.begin(); iter != v1.end(); iter++)
{
//v1.push_back(888); //错误, 循环时改变了容器容量
cout << (*iter) << endl;
}
}
若必须在循环体内改变容器大小,需要插入后立刻break,再重新遍历
int main() {
vector<int> v1{1, 2, 3};
for (auto iter = v1.begin(); iter != v1.end(); iter++)
{
v1.push_back(888);
break; //插入后立刻跳出循环
}
//重新遍历
for (auto iter = v1.begin(); iter != v1.end(); iter++)
{
cout << (*iter) << endl; //1,2,3,888
}
}
4.2 合理的清除容器的元素
int main() {
vector<int> v1{1, 2, 3};
while (!v1.empty())
{
auto iter = v1.begin(); //iter始终指向容器的开始元素
v1.erase(iter); //删除迭代器指向的元素
}
}