迭代器
迭代器的基本概念
迭代器类似于指针,它指向容器中的某个元素,并提供了访问和遍历容器元素的方法。STL 算法通过迭代器与容器交互。
迭代器的分类
C++ 中有 5 种迭代器类别,按功能从弱到强排列:
- 输入迭代器 (Input Iterator) - 只读,只能单向移动
- 输出迭代器 (Output Iterator) - 只写,只能单向移动
- 前向迭代器 (Forward Iterator) - 可读写,只能单向移动
- 双向迭代器 (Bidirectional Iterator) - 可读写,能双向移动
- 随机访问迭代器 (Random Access Iterator) - 可读写,能随机访问
如何实现自定义迭代器
下面是一个简单的自定义迭代器实现示例:
#include <iostream>
#include <iterator> // 需要包含这个头文件以使用迭代器相关类型
template <typename T>
class SimpleArray {
private:
T* data;
size_t size;
public: // 自定义迭代器类
class Iterator {
private:
T* ptr;
public: // 必要的类型定义 (STL 算法需要这些)
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = T&;
// 构造函数
explicit Iterator(T* p) : ptr(p) {}
// 解引用操作符
reference operator*() const { return *ptr; }
pointer operator->() const { return ptr; }
// 前缀递增
Iterator& operator++() {
++ptr;
return *this;
}
// 后缀递增
Iterator operator++(int) {
Iterator tmp = *this;
++ptr;
return tmp;
}
// 前缀递减
Iterator& operator--() {
--ptr;
return *this;
}
// 后缀递减
Iterator operator--(int) {
Iterator tmp = *this;
--ptr;
return tmp;
}
// 随机访问
Iterator operator+(difference_type n) const { return Iterator(ptr + n); }
Iterator operator-(difference_type n) const { return Iterator(ptr - n); }
difference_type operator-(const Iterator& other) const { return ptr - other.ptr; }
// 比较操作符
bool operator==(const Iterator& other) const { return ptr == other.ptr; }
bool operator!=(const Iterator& other) const { return ptr != other.ptr; }
bool operator<(const Iterator& other) const { return ptr < other.ptr; }
bool operator>(const Iterator& other) const { return ptr > other.ptr; }
bool operator<=(const Iterator& other) const { return ptr <= other.ptr; }
bool operator>=(const Iterator& other) const { return ptr >= other.ptr; }
// 复合赋值
Iterator& operator+=(difference_type n) { ptr += n; return *this; }
Iterator& operator-=(difference_type n) { ptr -= n; return *this; }
// 下标访问
reference operator[](difference_type n) const { return ptr[n]; }
};
// 构造函数
SimpleArray(size_t s) : size(s), data(new T[s]) {}
// 析构函数
~SimpleArray() { delete[] data; }
// 获取起始迭代器
Iterator begin() { return Iterator(data); }
// 获取结束迭代器
Iterator end() { return Iterator(data + size); }
// 获取元素引用
T& operator[](size_t index) { return data[index]; }
};
int main() {
SimpleArray<int> arr(5);
// 初始化数组
for (int i = 0; i < 5; ++i) { arr[i] = i * 10; }
// 使用迭代器遍历
for (auto it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << " "; }
std::cout << std::endl;
// 使用基于范围的for循环 (C++11)
for (auto val : arr) { std::cout << val << " "; }
std::cout << std::endl;
return 0;
}
迭代器实现的关键点
-
必要的类型定义:
using iterator_category = ...; // 迭代器类别 using value_type = ...; // 迭代器指向的元素类型 using difference_type = ...; // 两个迭代器之间的距离类型 using pointer = ...; // 指向元素的指针类型 using reference = ...; // 元素的引用类型
-
必须实现的操作符:
- 解引用操作符 (
operator*
) - 递增操作符 (
operator++
) - 相等/不等比较 (
operator==
,operator!=
)
- 解引用操作符 (
-
根据迭代器类别实现额外功能:
- 双向迭代器需要实现递减操作符 (
operator--
) - 随机访问迭代器需要实现算术运算和比较操作符
- 双向迭代器需要实现递减操作符 (
迭代器适配器
STL 提供了一些迭代器适配器,可以修改现有迭代器的行为:
- 反向迭代器 (reverse_iterator) - 逆向遍历
- 插入迭代器 (insert_iterator) - 将赋值操作转换为插入操作
back_insert_iterator
(push_back)front_insert_iterator
(push_front)insert_iterator
(insert)
- 流迭代器 (istream_iterator, ostream_iterator) - 用于输入输出流
性能考虑
迭代器的设计会影响容器的性能:
- 随机访问迭代器提供最快的访问速度
- 输入/输出迭代器通常用于流操作,性能较低
- 迭代器的解引用操作应该尽可能轻量