迭代器模式C++
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种顺序访问聚合对象元素的方法,而无需暴露聚合对象的内部表示。这种模式将遍历逻辑与聚合对象分离,使遍历操作可以独立于聚合结构变化。
迭代器模式的核心角色
- Iterator(迭代器接口):定义遍历元素的接口(如
hasNext()
、next()
) - ConcreteIterator(具体迭代器):实现迭代器接口,负责具体的遍历逻辑
- Aggregate(聚合接口):定义创建迭代器的接口(如
createIterator()
) - ConcreteAggregate(具体聚合):实现聚合接口,返回具体迭代器实例
C++实现示例
以下实现一个自定义集合类,并使用迭代器模式实现对集合元素的遍历:
#include <iostream>
#include <vector>
#include <string>
#include <memory>// 前向声明
template <typename T>
class Iterator;// 聚合接口
template <typename T>
class Aggregate {
public:virtual ~Aggregate() = default;virtual std::unique_ptr<Iterator<T>> createIterator() = 0;virtual size_t size() const = 0;virtual T& operator[](size_t index) = 0;virtual const T& operator[](size_t index) const = 0;
};// 迭代器接口
template <typename T>
class Iterator {
public:virtual ~Iterator() = default;virtual bool hasNext() const = 0;virtual T& next() = 0;virtual T& current() const = 0;
};// 具体聚合:自定义集合
template <typename T>
class CustomCollection : public Aggregate<T> {
private:std::vector<T> items;public:void add(const T& item) {items.push_back(item);}void remove(size_t index) {if (index < items.size()) {items.erase(items.begin() + index);}}size_t size() const override {return items.size();}T& operator[](size_t index) override {return items[index];}const T& operator[](size_t index) const override {return items[index];}// 创建迭代器std::unique_ptr<Iterator<T>> createIterator() override;
};// 具体迭代器:自定义集合迭代器
template <typename T>
class CustomIterator : public Iterator<T> {
private:CustomCollection<T>& collection;size_t currentIndex;public:CustomIterator(CustomCollection<T>& coll) : collection(coll), currentIndex(0) {}bool hasNext() const override {return currentIndex < collection.size();}T& next() override {if (hasNext()) {return collection[currentIndex++];}throw std::out_of_range("迭代器已到达末尾");}T& current() const override {if (currentIndex < collection.size()) {return collection[currentIndex];}throw std::out_of_range("迭代器已到达末尾");}
};// 实现createIterator方法
template <typename T>
std::unique_ptr<Iterator<T>> CustomCollection<T>::createIterator() {return std::make_unique<CustomIterator<T>>(*this);
}// 反向迭代器(额外实现,展示不同的遍历方式)
template <typename T>
class ReverseIterator : public Iterator<T> {
private:CustomCollection<T>& collection;int currentIndex;public:ReverseIterator(CustomCollection<T>& coll) : collection(coll) {currentIndex = coll.size() - 1;}bool hasNext() const override {return currentIndex >= 0;}T& next() override {if (hasNext()) {return collection[currentIndex--];}throw std::out_of_range("迭代器已到达开头");}T& current() const override {if (currentIndex >= 0) {return collection[currentIndex];}throw std::out_of_range("迭代器已到达开头");}
};// 为CustomCollection添加反向迭代器创建方法
template <typename T>
std::unique_ptr<Iterator<T>> createReverseIterator(CustomCollection<T>& collection) {return std::make_unique<ReverseIterator<T>>(collection);
}// 客户端代码:使用迭代器遍历集合
template <typename T>
void iterateCollection(Iterator<T>& iterator, const std::string& traversalType) {std::cout << traversalType << "遍历: ";while (iterator.hasNext()) {std::cout << iterator.next() << " ";}std::cout << std::endl;
}int main() {// 创建字符串集合CustomCollection<std::string> stringCollection;stringCollection.add("苹果");stringCollection.add("香蕉");stringCollection.add("橙子");stringCollection.add("葡萄");// 获取正向迭代器并遍历auto forwardIt = stringCollection.createIterator();iterateCollection(*forwardIt, "正向");// 获取反向迭代器并遍历auto reverseIt = createReverseIterator(stringCollection);iterateCollection(*reverseIt, "反向");// 创建整数集合CustomCollection<int> intCollection;intCollection.add(10);intCollection.add(20);intCollection.add(30);intCollection.add(40);// 遍历整数集合auto intIt = intCollection.createIterator();iterateCollection(*intIt, "整数正向");return 0;
}
代码解析
-
迭代器接口(
Iterator
):- 定义了遍历元素的标准接口:
hasNext()
(是否有下一个元素)、next()
(获取下一个元素)和current()
(获取当前元素) - 模板化设计使其可适用于不同类型的元素
- 定义了遍历元素的标准接口:
-
聚合接口(
Aggregate
):- 定义了创建迭代器的接口
createIterator()
,以及集合的基本操作 - 具体聚合类需实现这些接口,提供集合的实际功能
- 定义了创建迭代器的接口
-
具体实现:
CustomCollection
:基于std::vector
实现的自定义集合,实现了聚合接口CustomIterator
:正向迭代器,实现了从前往后的遍历逻辑ReverseIterator
:反向迭代器,展示了不同的遍历方式,无需修改集合本身
-
客户端使用:
- 客户端通过迭代器接口遍历集合,无需了解集合的内部结构
- 可根据需要选择不同的迭代器(正向、反向),实现灵活的遍历方式
迭代器模式的优缺点
优点:
- 分离了集合的遍历逻辑与集合本身,符合单一职责原则
- 客户端可以使用统一的接口遍历不同类型的集合,简化了代码
- 便于添加新的迭代器类型(如反向迭代、过滤迭代),符合开放-封闭原则
- 隐藏了集合的内部实现,提高了封装性
缺点:
- 增加了系统复杂度,需要额外的迭代器类
- 对于简单的集合,使用迭代器可能显得冗余
- 在某些情况下,迭代器可能不如直接访问集合高效
适用场景
- 当需要遍历不同类型的集合,且希望使用统一接口时
- 当希望隐藏集合的内部结构,只暴露遍历功能时
- 当需要多种遍历方式(如正向、反向、按条件过滤)时
C++标准库中的应用:
- C++ STL中的
std::iterator
及其派生类(如std::vector::iterator
) - 各种容器的
begin()
和end()
方法返回的迭代器 - 算法库中的通用算法(如
std::for_each
)通过迭代器操作容器
迭代器模式是C++标准库中应用最广泛的模式之一,它使得算法可以独立于容器类型而工作,极大地提高了代码的复用性和灵活性。