在C++的标准库中,容器和迭代器是紧密配合的设计,当我们自己实现一个自定义容器时,也需要同步实现对应的迭代器,才能让容器支持标准遍历语法,适配算法库的使用要求。迭代器的核心作用是封装容器内部元素的访问逻辑,让使用者不需要关心容器的底层存储结构,就能完成元素的遍历、访问和修改操作。

迭代器设计的核心要求
自定义迭代器需要满足几个基本条件,才能适配C++的遍历规范:
- 支持解引用操作,获取当前指向的元素
- 支持前置和后置自增操作,移动到下一个元素
- 支持相等和不相等比较,判断遍历是否结束
- 定义对应的类型别名,方便标准算法识别迭代器属性
自定义容器与迭代器实现示例
下面我们实现一个简单的动态数组容器,同时为其实现对应的迭代器,完整代码如下:
#include <iostream>
#include <cstddef>
// 自定义动态数组容器
template <typename T>
class MyArray {
private:
T* data;
size_t capacity;
size_t size;
public:
// 迭代器类定义
class Iterator {
private:
T* ptr; // 指向当前元素的指针
public:
// 类型别名,适配标准迭代器要求
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = T&;
// 构造函数
Iterator(T* p = nullptr) : ptr(p) {}
// 解引用运算符重载
reference operator*() const {
return *ptr;
}
// 箭头运算符重载
pointer operator->() const {
return ptr;
}
// 前置自增运算符重载
Iterator& operator++() {
++ptr;
return *this;
}
// 后置自增运算符重载
Iterator operator++(int) {
Iterator temp = *this;
++ptr;
return temp;
}
// 相等比较运算符重载
bool operator==(const Iterator& other) const {
return ptr == other.ptr;
}
// 不相等比较运算符重载
bool operator!=(const Iterator& other) const {
return ptr != other.ptr;
}
};
// 容器构造函数
MyArray(size_t initCapacity = 10) : capacity(initCapacity), size(0) {
data = new T[capacity];
}
// 容器析构函数
~MyArray() {
delete[] data;
}
// 添加元素
void push_back(const T& val) {
if (size >= capacity) {
// 扩容逻辑
capacity *= 2;
T* newData = new T[capacity];
for (size_t i = 0; i < size; ++i) {
newData[i] = data[i];
}
delete[] data;
data = newData;
}
data[size++] = val;
}
// 返回起始迭代器
Iterator begin() {
return Iterator(data);
}
// 返回结束迭代器
Iterator end() {
return Iterator(data + size);
}
// 获取容器大小
size_t getSize() const {
return size;
}
};
// 测试代码
int main() {
MyArray<int> arr;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
arr.push_back(4);
// 使用迭代器遍历容器
std::cout << "遍历容器元素: ";
for (auto it = arr.begin(); it != arr.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用范围for循环遍历(依赖迭代器实现)
std::cout << "范围for遍历结果: ";
for (int val : arr) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
代码逻辑解析
上述实现中,我们把迭代器作为自定义容器MyArray的内部类,这样可以直接访问容器的私有成员。迭代器内部用指针保存当前位置,通过重载对应的运算符实现遍历相关操作。容器提供begin和end方法返回起始和结束迭代器,这样就能支持标准for循环和范围for循环的遍历方式。
如果需要在迭代器中支持更多操作,比如随机访问的加减操作、下标访问等,可以继续重载对应的运算符,同时修改iterator_category的类型为std::random_access_iterator_tag,让迭代器符合随机访问迭代器的规范。
迭代器模式的体现
这里的实现符合迭代器模式的核心思想:将容器的遍历逻辑和容器本身的存储逻辑分离,使用者只需要和迭代器接口交互,不需要知道容器底层是用数组、链表还是其他结构存储元素。如果后续我们修改MyArray的底层存储结构,只要迭代器的接口保持不变,上层使用迭代器的代码就不需要做任何修改,大大降低了代码的耦合度。