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. 图算法:深度优先、广度优先遍历

相关推荐
NAGNIP2 小时前
万字长文!回归模型最全讲解!
算法·面试
知乎的哥廷根数学学派2 小时前
面向可信机械故障诊断的自适应置信度惩罚深度校准算法(Pytorch)
人工智能·pytorch·python·深度学习·算法·机器学习·矩阵
txinyu的博客3 小时前
解析业务层的key冲突问题
开发语言·c++·分布式
666HZ6664 小时前
数据结构2.0 线性表
c语言·数据结构·算法
SmartRadio4 小时前
ESP32添加修改蓝牙名称和获取蓝牙连接状态的AT命令-完整UART BLE服务功能后的完整`main.c`代码
c语言·开发语言·c++·esp32·ble
实心儿儿4 小时前
Linux —— 基础开发工具5
linux·运维·算法
charlie1145141915 小时前
嵌入式的现代C++教程——constexpr与设计技巧
开发语言·c++·笔记·单片机·学习·算法·嵌入式
清木铎6 小时前
leetcode_day4_筑基期_《绝境求生》
算法
清木铎7 小时前
leetcode_day10_筑基期_《绝境求生》
算法
j_jiajia7 小时前
(一)人工智能算法之监督学习——KNN
人工智能·学习·算法