C++ 迭代器模式详解

迭代器模式(Iterator Pattern)是一种行为设计模式,它提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

核心概念

设计原则

迭代器模式遵循以下设计原则:

  1. 单一职责原则:将遍历逻辑与集合分离

  2. 开闭原则:可以引入新的集合和迭代器而不修改现有代码

  3. 封装性:隐藏集合的内部实现细节

主要优点

  1. 统一接口:为不同集合提供统一的遍历方式

  2. 多遍历支持:可以同时进行多个遍历

  3. 解耦合:将集合与遍历逻辑分离

  4. 延迟遍历:支持惰性求值和按需遍历

模式结构

主要组件

  1. Iterator(迭代器接口)

    • 定义访问和遍历元素的接口

  2. ConcreteIterator(具体迭代器)

    • 实现迭代器接口

    • 跟踪当前遍历位置

  3. Aggregate(聚合接口)

    • 定义创建迭代器对象的接口

  4. ConcreteAggregate(具体聚合)

    • 实现创建迭代器的接口

    • 返回具体迭代器的实例

完整代码示例

#include <iostream>
#include <vector>
#include <memory>
#include <stdexcept>

// ==================== 迭代器接口 ====================
template <typename T>
class Iterator {
public:
    virtual void first() = 0;           // 重置到第一个元素
    virtual void next() = 0;            // 移动到下一个元素
    virtual bool isDone() const = 0;    // 是否遍历完成
    virtual T currentItem() const = 0;  // 获取当前元素
    virtual ~Iterator() = default;
};

// ==================== 聚合接口 ====================
template <typename T>
class Aggregate {
public:
    virtual std::unique_ptr<Iterator<T>> createIterator() = 0;
    virtual ~Aggregate() = default;
};

// ==================== 具体聚合 ====================
template <typename T>
class ConcreteAggregate : public Aggregate<T> {
    std::vector<T> items_;
    
public:
    void addItem(const T& item) {
        items_.push_back(item);
    }
    
    T getItem(size_t index) const {
        if (index >= items_.size()) {
            throw std::out_of_range("索引超出范围");
        }
        return items_[index];
    }
    
    size_t size() const {
        return items_.size();
    }
    
    std::unique_ptr<Iterator<T>> createIterator() override;
};

// ==================== 具体迭代器 ====================
template <typename T>
class ConcreteIterator : public Iterator<T> {
    const ConcreteAggregate<T>& aggregate_;
    size_t current_;
    
public:
    explicit ConcreteIterator(const ConcreteAggregate<T>& aggregate)
        : aggregate_(aggregate), current_(0) {}
    
    void first() override {
        current_ = 0;
    }
    
    void next() override {
        if (!isDone()) {
            ++current_;
        }
    }
    
    bool isDone() const override {
        return current_ >= aggregate_.size();
    }
    
    T currentItem() const override {
        if (isDone()) {
            throw std::out_of_range("迭代器已到达末尾");
        }
        return aggregate_.getItem(current_);
    }
};

// 在类外定义createIterator
template <typename T>
std::unique_ptr<Iterator<T>> ConcreteAggregate<T>::createIterator() {
    return std::make_unique<ConcreteIterator<T>>(*this);
}

// ==================== 客户端代码 ====================
int main() {
    std::cout << "=== 迭代器模式演示 ===" << std::endl;
    
    // 创建具体聚合对象
    ConcreteAggregate<std::string> aggregate;
    aggregate.addItem("第一个元素");
    aggregate.addItem("第二个元素");
    aggregate.addItem("第三个元素");
    aggregate.addItem("第四个元素");
    
    // 创建迭代器
    auto iterator = aggregate.createIterator();
    
    // 使用迭代器遍历
    std::cout << "\n正向遍历:" << std::endl;
    for (iterator->first(); !iterator->isDone(); iterator->next()) {
        std::cout << iterator->currentItem() << std::endl;
    }
    
    // 重置迭代器
    iterator->first();
    
    // 跳过第一个元素
    std::cout << "\n跳过第一个元素:" << std::endl;
    iterator->next();
    while (!iterator->isDone()) {
        std::cout << iterator->currentItem() << std::endl;
        iterator->next();
    }
    
    // 尝试访问结束后的元素
    try {
        std::cout << "\n尝试访问结束后的元素:" << std::endl;
        std::cout << iterator->currentItem() << std::endl;
    } catch (const std::out_of_range& e) {
        std::cerr << "错误: " << e.what() << std::endl;
    }
    
    return 0;
}

模式变体

1. 反向迭代器

template <typename T>
class ReverseIterator : public Iterator<T> {
    const ConcreteAggregate<T>& aggregate_;
    size_t current_;
    
public:
    explicit ReverseIterator(const ConcreteAggregate<T>& aggregate)
        : aggregate_(aggregate), current_(aggregate.size() - 1) {}
    
    void first() override {
        current_ = aggregate_.size() - 1;
    }
    
    void next() override {
        if (!isDone()) {
            --current_;
        }
    }
    
    bool isDone() const override {
        return current_ >= aggregate_.size(); // 处理size_t下溢
    }
    
    T currentItem() const override {
        if (isDone()) {
            throw std::out_of_range("迭代器已到达开头");
        }
        return aggregate_.getItem(current_);
    }
};

// 在ConcreteAggregate中添加
std::unique_ptr<Iterator<T>> createReverseIterator() {
    return std::make_unique<ReverseIterator<T>>(*this);
}

2. 过滤迭代器

template <typename T, typename Predicate>
class FilterIterator : public Iterator<T> {
    const ConcreteAggregate<T>& aggregate_;
    Iterator<T>& iterator_;
    Predicate predicate_;
    
public:
    FilterIterator(const ConcreteAggregate<T>& aggregate, 
                  Iterator<T>& iterator,
                  Predicate predicate)
        : aggregate_(aggregate), iterator_(iterator), predicate_(predicate) {}
    
    void first() override {
        iterator_.first();
        skipNonMatching();
    }
    
    void next() override {
        iterator_.next();
        skipNonMatching();
    }
    
    bool isDone() const override {
        return iterator_.isDone();
    }
    
    T currentItem() const override {
        return iterator_.currentItem();
    }
    
private:
    void skipNonMatching() {
        while (!iterator_.isDone() && !predicate_(iterator_.currentItem())) {
            iterator_.next();
        }
    }
};

// 使用示例
auto iterator = aggregate.createIterator();
auto isEven = [](int n) { return n % 2 == 0; };
FilterIterator<int, decltype(isEven)> filterIterator(aggregate, *iterator, isEven);

实际应用场景

  1. STL容器:C++标准库中的迭代器实现

  2. 树形结构遍历:支持不同遍历方式(前序、中序、后序)

  3. 数据库查询结果:遍历查询结果集

  4. 文件系统遍历:递归遍历目录结构

  5. 图算法:深度优先、广度优先遍历

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值