【C++】标准模板库STL-迭代器
在C++标准模板库(STL)中,迭代器(Iterators)是一类对象,它们提供了一种统一的接口来遍历和元素进行交互。迭代器可以被视为一种泛化的指针,它们允许程序员在不知道底层容器实现细节的情况下,对容器中的元素进行访问和操作。
迭代器是STL的基石之一,因为它们允许算法与容器进行解耦,这意味着同一个算法可以用于不同的容器类型。
1. 迭代器特性
- 迭代器是对象:迭代器本身是对象,可以存储当前遍历到的位置的状态。
- 迭代器是轻量级:迭代器通常不复制容器中的元素,而是提供一个访问容器元素的途径。
- 迭代器是可变的:迭代器可以改变其所指向的元素的值。
2. 迭代器分类
- 输入迭代器(Input Iterators)
- 允许你读取每个元素一次,用于流式的输入。
- 支持 ++ 递增操作和相等性比较。
- 只能进行元素的读取,不支持元素的写入。
- 输出迭代器(Output Iterators)
- 主要用于写入序列,如
std::copy的输出参数。 - 支持
++递增操作和相等性比较,以及元素的写入。
- 前向迭代器(Forward Iterators)
- 结合了输入和输出迭代器的特性,允许多次读取和写入。
- 支持单向遍历,只能前进不能后退。
- 双向迭代器(Bidirectional Iterators)
- 扩展了前向迭代器,允许元素的双向遍历(前进和后退)。
- 支持
--递减操作,可以向后移动到前一个元素。
- 随机访问迭代器(Random Access Iterators)
- 双向迭代器加上随机访问能力,可以快速跳转到任意位置。
- 支持所有的算术操作,如
+,-,+=,-=,以及比较操作>,<,>=,<=。
- 容器适配器迭代器(Container Adaptor Iterators)
- 例如
std::stack,std::queue, 和std::priority_queue提供的迭代器。 - 这些迭代器的行为依赖于适配器的实现,通常限制了迭代器的操作范围。
- 代码示例:
1 std::vector<int> vec = {1, 2, 3, 4, 5}; 2 std::vector<int>::iterator it = vec.begin(); // 随机访问迭代器 3 4 // 随机访问迭代器操作 5 it += 2; // 跳转到第三个元素 6 it -= 1; // 跳转到第四个元素 7 int val = it[2]; // 访问第六个元素(从零开始计数) 8 9 std::list<int> lst = {1, 2, 3, 4, 5}; 10 std::list<int>::iterator lit = lst.begin(); // 前向迭代器 11 12 // 前向迭代器操作 13 ++lit; // 移动到下一个元素 14 lit++; // 移动到下一个元素(后置递增)
3. 迭代器操作
- 解引用操作符(*):访问迭代器指向的元素。
- 成员访问操作符(->):通过迭代器访问对象的成员。
- 前缀递增(++)和后缀递增(++):将迭代器移动到下一个元素。
- 前缀递减(--)和后缀递减(--):将迭代器移动到上一个元素。
- 相等和不相等操作符(==, !=):比较两个迭代器是否相等或不相等。
4. 示例代码
在C++ STL中,迭代器允许你以统一的方式访问和操作容器中的元素。以下是一些常见的迭代器操作:
4.1. 迭代器初始化
1 std::vector<int> vec = {1, 2, 3, 4, 5}; 2 std::vector<int>::iterator it; // 声明迭代器
4.2. 遍历容器
1 for (it = vec.begin(); it != vec.end(); ++it) { 2 // *it 访问当前元素 3 // it->member 访问当前元素的成员变量 4 }
4.3. 直接访问元素
1 auto val = *it; // 获取当前迭代器指向的元素的值
4.4. 递增和递减迭代器
1 ++it; // 前置递增 2 it++; // 后置递增 3 --it; // 前置递减 4 it--; // 后置递减
4.5. 比较迭代器
1 if (it == vec.begin()) { 2 // it 指向容器的开始 3 } 4 5 if (it != vec.end()) { 6 // it 不是容器的结束 7 }
4.6. 随机访问迭代器(如 std::vector 或 std::array)
1 std::vector<int>::iterator it = vec.begin() + 2; // 直接跳转到第三个元素
4.7. 使用 std::advance 函数
1 std::advance(it, 3); // 将迭代器向前移动3个位置
4.8. 范围基 for 循环(C++11及以后)
1 for (auto& val : vec) { 2 // val 是容器中的元素的引用 3 }
4.9. 使用迭代器访问容器元素的成员
1 struct Node { 2 int value; 3 // ... 4 }; 5 6 std::vector<Node> nodes; 7 for (auto& node : nodes) { 8 node.value = 1; // 直接修改当前节点的 value 成员 9 }
4.10. 迭代器失效
在某些操作(如插入、删除、重新分配)后,迭代器可能会失效。因此,需要谨慎地管理迭代器的生命周期。
1 vec.erase(it); // 删除当前迭代器指向的元素后,该迭代器失效
4.11. 注意
- 迭代器的类型应与容器类型匹配。
- 迭代器操作应该在容器的有效期内。
- 某些容器操作可能导致迭代器失效,例如 erase、clear 或容器的重新分配。
- 迭代器的比较和算术操作取决于迭代器的类别(如输入迭代器、前向迭代器、随机访问迭代器等)。
时间:2024年5月1日

【C++】标准模板库STL-迭代器
浙公网安备 33010602011771号