第四节 · 游走于每一处 · 迭代器
在学习 string 和 vector 时,我们已经多次见到了迭代器(Iterator)。迭代器是 C++ 标准库的核心概念之一,它提供了一种统一的方式来访问容器中的元素。
如果把容器比作一条街道,元素比作街道上的房子,那么迭代器就像是一个邮递员——它知道如何从一家走到另一家,而不需要知道街道的具体布局。
什么是迭代器
迭代器是一种类似指针的对象,它可以:
指向容器中的某个元素
通过递增/递减移动到相邻的元素
通过解引用访问它指向的元素
最简单的理解方式:迭代器就是"泛化的指针"。
vector<int> v = {10, 20, 30, 40, 50};
// 获取指向第一个元素的迭代器
vector<int>::iterator it = v.begin();
// 解引用,获取元素的值
cout << *it << endl; // 10
// 移动到下一个元素
++it;
cout << *it << endl; // 20
// 移动到上一个元素
--it;
cout << *it << endl; // 10begin() 和 end()
每个标准库容器都提供 begin() 和 end() 成员函数:
begin():返回指向第一个元素的迭代器end():返回指向最后一个元素之后的位置的迭代器(不是最后一个元素!)
end() 指向的是一个"虚拟"的位置,不能解引用。它的作用是标记遍历的终点。
迭代器的运算
不同类型的迭代器支持不同的运算。对于 vector 和 string,它们的迭代器是随机访问迭代器,支持所有运算:
const 迭代器
如果你不想(或不能)通过迭代器修改元素,可以使用 const 迭代器:
当容器本身是 const 的时候,begin() 和 end() 也会返回 const_iterator。
反向迭代器
如果想从后往前遍历,可以使用反向迭代器:
注意:反向迭代器的 ++ 操作是向前移动(即向数组开头方向)。
迭代器失效
使用迭代器时需要特别注意:某些操作可能会导致迭代器失效。
会导致迭代器失效的操作包括:
push_back():可能导致 vector 重新分配内存insert():插入点之后的所有迭代器失效erase():删除点及之后的所有迭代器失效clear():所有迭代器失效
安全的做法是在这些操作后重新获取迭代器:
在遍历时删除元素
一个常见的错误是在遍历时删除元素:
正确的做法:
迭代器与算法
标准库的算法几乎都是通过迭代器来操作容器的:
这就是迭代器的强大之处:算法只需要知道如何使用迭代器,而不需要知道具体是什么容器。同一个 sort 算法可以用于 vector、deque、普通数组等任何支持随机访问的容器。
迭代器的类型
C++ 定义了几种迭代器类型,按功能从弱到强排列:
输入迭代器:只能单向读取
输出迭代器:只能单向写入
前向迭代器:可以单向多次读写
双向迭代器:可以双向移动(如
list)随机访问迭代器:支持所有运算(如
vector、deque、普通数组)
不同的算法对迭代器有不同的要求。比如 sort 需要随机访问迭代器,而 find 只需要输入迭代器。
迭代器是连接容器和算法的桥梁,是 C++ 泛型编程的基石。理解迭代器,你就能更好地使用标准库的强大功能。
习题
使用迭代器遍历一个 vector,将其中所有偶数翻倍。
使用反向迭代器,将一个字符串倒序输出。
编写一个函数,使用迭代器在 vector 中查找第一个大于给定值的元素。
Last updated