C++中的迭代器是一种访问容器(如数组、向量、列表等)中元素的对象,类似于指针。
文章目录
- 基本类型
- 基本用法
- 示例代码
- 遍历`std::vector`
- 修改`std::vector`中的元素
- 使用`std::list`的双向迭代器
- 使用erase删除元素
- 注意事项
C++中的迭代器是一种访问容器(如数组、向量、列表等)中元素的对象,类似于指针。迭代器提供了一种通用的、容器无关的访问容器元素的方法,使得无需知道容器的内部结构就可以遍历容器。这里简要介绍迭代器的基本用法和一些常见操作。
基本类型
C++ STL中定义了几种类型的迭代器,包括:
- 输入迭代器:只能向前移动(单次递增),只读访问。
- 输出迭代器:只能向前移动,只写访问。
- 前向迭代器:只能向前移动,可读写。
- 双向迭代器:可向前和向后移动,可读写。
- 随机访问迭代器:可以直接跳到任何位置,可读写,支持全部迭代器操作。
基本用法
迭代器的使用大多遵循以下模式:
-
获取迭代器:使用容器的
.begin()和.end()方法获取指向容器第一个元素和末尾(最后一个元素的下一个位置)的迭代器。 -
遍历容器:使用迭代器遍历容器中的元素。
-
访问元素:通过解引用迭代器(使用
*操作符)访问其当前指向的元素。 -
修改元素(如果允许):通过解引用迭代器并赋值。
示例代码
以下是一些迭代器的示例代码,展示了如何在C++中使用迭代器遍历和操作容器。
遍历std::vector
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用迭代器遍历vectorfor (auto it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " "; // 访问元素}std::cout << std::endl;return 0;
}
修改std::vector中的元素
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用迭代器修改vector中的元素for (auto it = vec.begin(); it != vec.end(); ++it) {*it *= 2; // 将每个元素乘以2}return 0;
}
使用std::list的双向迭代器
#include <iostream>
#include <list>int main() {std::list<int> lst = {1, 2, 3, 4, 5};// 使用迭代器正向遍历liststd::cout << "Forward: ";for (auto it = lst.begin(); it != lst.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用迭代器反向遍历liststd::cout << "Backward: ";for (auto it = lst.rbegin(); it != lst.rend(); ++it) {std::cout << *it << " ";}std::cout << std::endl;return 0;
}
使用erase删除元素
在使用迭代器遍历容器的同时删除元素时,需要特别注意保持迭代器的有效性。由于删除元素会使指向被删除元素的迭代器及其之后元素的迭代器失效,正确的做法是使用erase函数返回的迭代器继续遍历。这种做法适用于所有支持erase方法的容器,如std::vector, std::list, std::deque等。
下面是使用迭代器在遍历过程中删除元素的示例,我将使用std::vector<int>来演示:
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 使用迭代器遍历并删除特定元素// 例如,删除所有偶数for (auto it = vec.begin(); it != vec.end();) {if (*it % 2 == 0) {it = vec.erase(it); // 删除元素,并用erase返回的迭代器更新it} else {++it; // 只有在不删除元素的情况下才向前移动迭代器}}// 打印剩余元素std::cout << "Remaining elements: ";for (const auto& element : vec) {std::cout << element << " ";}std::cout << std::endl;return 0;
}
在这个示例中,我们遍历vec,使用条件判断找出所有偶数元素,并在找到它们时将它们从vector中删除。注意,当调用erase时,我们不需要手动递增迭代器,因为erase会返回指向当前被删除元素下一个元素的有效迭代器。这是安全删除容器中元素的关键,避免了迭代器失效导致的未定义行为。
对于std::list和其他容器,这种删除元素的模式是类似的,但是要记住,不同类型的容器在删除元素时性能表现不同。例如,std::list的erase操作通常比std::vector的快,因为链表删除元素不需要移动其他元素。
注意事项
- 使用迭代器时需要注意迭代器失效的问题。某些操作(如删除或插入元素)可能会导致迭代器失效,此时继续使用这些迭代器可能会导致未定义行为。
- 当需要在遍历过程中修改容器时(如插入或删除元素),需要小心处理迭代器,确保操作安全。
迭代器是C++ STL的核心概念之一,熟练掌握迭代器的使用对于高效地使用C++ STL容器至关重要。