【第22节】C++设计模式(行为模式)-Iterator(迭代器)模式

news2025/3/13 18:59:53

一、问题背景

        Iterator 模式是设计模式中最为常见和实用的模式之一。它的核心思想是将对聚合对象的遍历操作封装到一个独立的类中,从而避免暴露聚合对象的内部表示。通过 Iterator 模式,我们可以实现对聚合对象的统一遍历接口,而不需要关心聚合对象的具体实现细节。

        在实际开发中,Iterator 模式的应用非常广泛。例如,在实现 Composite 模式、Flyweight 模式、Observer 模式时,我们经常会使用 STL 提供的 Iterator 来遍历 `Vector` 或 `List` 等数据结构。Iterator 模式不仅简化了遍历操作,还提高了代码的可维护性和可扩展性。

二、模式选择

        Iterator 模式的典型结构图如下:

在 Iterator 模式中,主要包含以下几个角色:

(1)Aggregate(聚合):定义创建 Iterator 对象的接口。
(2)ConcreteAggregate(具体聚合):实现 Aggregate 接口,返回一个具体的 Iterator 实例。
(3)Iterator(迭代器):定义遍历聚合对象的接口。
(4)ConcreteIterator(具体迭代器):实现 Iterator 接口,负责遍历具体的聚合对象。

        通过这种设计,Iterator 模式将聚合对象的遍历逻辑与其内部实现分离,使得聚合对象可以独立于遍历逻辑进行修改。

三、代码实现

        下面我们将通过一个完整的 C++ 代码示例来展示如何实现 Iterator 模式。为了方便初学者的学习和参考,代码将包含详细的注释。

代码片段 1:Aggregate.h

// Aggregate.h
#ifndef _AGGREGATE_H_
#define _AGGREGATE_H_

class Iterator;
typedef int Object;  // 定义聚合对象中存储的数据类型

// Aggregate 类:定义创建 Iterator 对象的接口
class Aggregate {
public:
    virtual ~Aggregate();
    virtual Iterator* CreateIterator() = 0;  // 创建迭代器
    virtual Object GetItem(int idx) = 0;     // 获取指定位置的元素
    virtual int GetSize() = 0;               // 获取聚合对象的大小
protected:
    Aggregate();
private:
};

// ConcreteAggregate 类:具体聚合类,实现 Aggregate 接口
class ConcreteAggregate : public Aggregate {
public:
    enum { SIZE = 3 };  // 定义聚合对象的大小
    ConcreteAggregate();
    ~ConcreteAggregate();
    Iterator* CreateIterator();  // 创建迭代器
    Object GetItem(int idx);     // 获取指定位置的元素
    int GetSize();               // 获取聚合对象的大小
protected:
private:
    Object _objs[SIZE];  // 聚合对象中存储的数据
};

#endif //~_AGGREGATE_H_

代码片段 2:Aggregate.cpp

// Aggregate.cpp
#include "Aggregate.h"
#include "Iterator.h"
#include <iostream>
using namespace std;

// Aggregate 类的实现
Aggregate::Aggregate() {
    // 构造函数
}

Aggregate::~Aggregate() {
    // 析构函数
}

// ConcreteAggregate 类的实现
ConcreteAggregate::ConcreteAggregate() {
    // 初始化聚合对象中的数据
    for (int i = 0; i < SIZE; i++) {
        _objs[i] = i;
    }
}

ConcreteAggregate::~ConcreteAggregate() {
    // 析构函数
}

Iterator* ConcreteAggregate::CreateIterator() {
    // 创建具体的迭代器对象
    return new ConcreteIterator(this);
}

Object ConcreteAggregate::GetItem(int idx) {
    // 获取指定位置的元素
    if (idx < this->GetSize()) {
        return _objs[idx];
    } else {
        return -1;  // 如果索引越界,返回 -1
    }
}

int ConcreteAggregate::GetSize() {
    // 获取聚合对象的大小
    return SIZE;
}

代码片段 3:Iterator.h

// Iterator.h
#ifndef _ITERATOR_H_
#define _ITERATOR_H_

class Aggregate;
typedef int Object;  // 定义聚合对象中存储的数据类型

// Iterator 类:定义遍历聚合对象的接口
class Iterator {
public:
    virtual ~Iterator();
    virtual void First() = 0;          // 将迭代器指向第一个元素
    virtual void Next() = 0;           // 将迭代器指向下一个元素
    virtual bool IsDone() = 0;         // 判断是否遍历结束
    virtual Object CurrentItem() = 0;  // 获取当前元素
protected:
    Iterator();
private:
};

// ConcreteIterator 类:具体迭代器类,实现 Iterator 接口
class ConcreteIterator : public Iterator {
public:
    ConcreteIterator(Aggregate* ag, int idx = 0);  // 构造函数
    ~ConcreteIterator();
    void First();          // 将迭代器指向第一个元素
    void Next();           // 将迭代器指向下一个元素
    bool IsDone();         // 判断是否遍历结束
    Object CurrentItem();  // 获取当前元素
protected:
private:
    Aggregate* _ag;  // 聚合对象
    int _idx;        // 当前索引
};

#endif //~_ITERATOR_H_

代码片段 4:Iterator.cpp

// Iterator.cpp
#include "Iterator.h"
#include "Aggregate.h"
#include <iostream>
using namespace std;

// Iterator 类的实现
Iterator::Iterator() {
    // 构造函数
}

Iterator::~Iterator() {
    // 析构函数
}

// ConcreteIterator 类的实现
ConcreteIterator::ConcreteIterator(Aggregate* ag, int idx) {
    this->_ag = ag;  // 初始化聚合对象
    this->_idx = idx;  // 初始化当前索引
}

ConcreteIterator::~ConcreteIterator() {
    // 析构函数
}

Object ConcreteIterator::CurrentItem() {
    // 获取当前元素
    return _ag->GetItem(_idx);
}

void ConcreteIterator::First() {
    // 将迭代器指向第一个元素
    _idx = 0;
}

void ConcreteIterator::Next() {
    // 将迭代器指向下一个元素
    if (_idx < _ag->GetSize()) {
        _idx++;
    }
}

bool ConcreteIterator::IsDone() {
    // 判断是否遍历结束
    return (_idx == _ag->GetSize());
}

代码片段 5:main.cpp

// main.cpp
#include "Iterator.h"
#include "Aggregate.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) {
    // 创建聚合对象
    Aggregate* ag = new ConcreteAggregate();

    // 创建迭代器对象
    Iterator* it = ag->CreateIterator();

    // 遍历聚合对象
    for (; !(it->IsDone()); it->Next()) {
        cout << it->CurrentItem() << endl;
    }

    // 释放内存
    delete it;
    delete ag;

    return 0;
}

代码说明

(1)Aggregate 类:定义了创建 Iterator 对象的接口,并提供了获取聚合对象大小和元素的方法。
(2)ConcreteAggregate 类:实现了 Aggregate 接口,内部维护了一个固定大小的数组。
(3)Iterator 类:定义了遍历聚合对象的接口,包括移动到第一个元素、移动到下一个元素、判断是否遍历结束以及获取当前元素的方法。
(4)ConcreteIterator 类:实现了 Iterator 接口,负责遍历 ConcreteAggregate 对象。

 

四、总结讨论

        Iterator 模式的应用非常广泛,尤其是在需要对聚合对象进行遍历时。通过将遍历逻辑封装到独立的 Iterator 类中,我们可以实现以下优点:

(1)简化遍历操作:客户端代码只需要调用 Iterator 的接口即可完成遍历,无需关心聚合对象的内部实现。
(2)提高代码复用性:可以为不同的聚合对象提供统一的遍历接口。
(3)增强灵活性:可以在不修改聚合对象的情况下,扩展或修改遍历逻辑。

        在实际开发中,STL 提供的 Iterator 就是一个典型的应用。例如,我们可以使用 `std::vector<int>::iterator` 来遍历 `std::vector<int>`,而无需关心 `std::vector` 的内部实现。

        Iterator 模式通过将对聚合对象的遍历操作封装到独立的类中,实现了遍历逻辑与聚合对象的解耦。这种设计模式不仅简化了代码结构,还提高了代码的可维护性和可扩展性。在实际开发中,Iterator 模式是处理聚合对象遍历问题的首选方案。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2311447.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyTorch基础语法万字解析

第一章&#xff1a;张量基础&#xff08;Tensor Fundamentals&#xff09; 1.1 张量创建 在PyTorch中&#xff0c;张量&#xff08;Tensor&#xff09;是用于表示数据的基本单元。它类似于NumPy中的数组&#xff0c;但额外支持GPU加速和自动微分功能。以下是几种创建张量的方…

eclipse查看源码

查看 Collection 源码的步骤 打开 Eclipse。 在代码中定位到 Collection 接口&#xff1a; 例如&#xff0c;在代码中输入 Collection&#xff0c;然后按住 Ctrl 键并单击 Collection。 或者直接在代码中使用 Collection 的地方按 F3 键。 如果源码已关联&#xff1a; Ecl…

robot:生而为奴

英文单词 robot&#xff0c;含义是”机器人“。 robot n.机器人 但其实&#xff0c;robot 这个单词的字面义&#xff0c;是生而为奴&#xff1a; robot rob打劫、搜刮 ot &#xff08;天生&#xff09;被剥削者 生而为奴 单词 bot&#xff0c;也指机器人&#xff0c;它是…

操作系统 2.3-用户级线程

多进程的回顾 多进程概念&#xff1a; 操作系统能够同时管理多个进程&#xff08;PID:1, PID:2, PID:3&#xff09;&#xff0c;每个进程可以独立执行一系列指令。 进程结构&#xff1a; 每个进程拥有自己的代码段、数据段、堆和栈。 进程控制块&#xff08;PCB&#xff09;…

解决火绒启动时,报安全服务异常,无法保障计算机安全

1.找到控制面板-安全和维护-更改用户账户控制设置 重启启动电脑解决。

小程序事件系统 —— 32 事件系统 - 事件分类以及阻止事件冒泡

在微信小程序中&#xff0c;事件分为 冒泡事件 和 非冒泡事件 &#xff1a; 冒泡事件&#xff1a;当一个组件的事件被触发后&#xff0c;该事件会向父节点传递&#xff1b;&#xff08;如果父节点中也绑定了一个事件&#xff0c;父节点事件也会被触发&#xff0c;也就是说子组…

STM32点亮LED灯

1.1 介绍&#xff1a; LED模块。它的控制方法非常简单&#xff0c;要想点亮LED&#xff0c;只要让它两端有一定的电压就可以&#xff1b;实验中&#xff0c;我们通过编程控制信号端S的高低电平&#xff0c;从而控制LED的亮灭。我们提供一个测试代码控制LED模块上实现闪烁的效果…

C++ primer plus 第七节 函数探幽完结版

系列文章目录 C primer plus 第一节 步入C-CSDN博客 C primer plus 第二节 hello world刨析-CSDN博客 C primer plus 第三节 数据处理-CSDN博客 C primer plus 第四节 复合类型-CSDN博客 C primer plus 第五节 循环-CSDN博客 C primier plus 第七节 函数探幽第一部分-CSDN博客 …

打破界限!家电行业3D数字化营销,线上线下无缝对接

家电行业正步入从增量市场向存量市场的转型期&#xff0c;消费者的观念日益成熟&#xff0c;对产品体验和服务质量的要求愈发严格。无论是线上电商平台还是线下实体店铺&#xff0c;提供个性化、增强体验感的产品与服务已成为家电市场未来发展的核心动力。51建模网凭借“3D数字…

13 【HarmonyOS NEXT】 仿uv-ui组件开发之Avatar组件进阶指南(四)

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; 文章目录 补充内容第四篇&#xff1a;打造高性能Avatar组件的终极优化秘籍1. 性能优化策略1.1 状态管理优化1.2 渲染性能优化 2. 资源优化2.1 图片…

[Vue warn]: Duplicate keys detected: ‘xxx‘. This may cause an update error.

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

设计模式 - 工厂模式 精准梳理精准记忆

1、代码片段 - 带入理解 一、核心模式分类 简单工厂模式&#xff08;编程习惯&#xff0c;非 GoF 设计模式&#xff09;工厂方法模式&#xff08;GoF 创建型模式&#xff09;抽象工厂模式&#xff08;GoF 创建型模式&#xff09; 二、演变过程&#xff1a;咖啡店案例 初始实现…

NVIDIA(英伟达) GPU 芯片架构发展史

GPU 性能的关键参数 CUDA 核心数量&#xff08;个&#xff09;&#xff1a;决定了 GPU 并行处理能力&#xff0c;在 AI 等并行计算类业务下&#xff0c;CUDA 核心越多性能越好。 显存容量&#xff08;GB&#xff09;&#xff1a;决定了 GPU 加载数据量的大小&#xff0c;在 AI…

springboot项目使用中创InforSuiteAS替换tomcat

springboot项目使用中创InforSuiteAS替换tomcat 学习地址一、部署InforSuiteAS1、部署2、运行 二、springboot项目打包成war包 特殊处理1、pom文件处理1、排除内嵌的tomcat包2、新增tomcat、javax.servlet-api3、打包格式设置为war4、打包后的项目名称5、启动类修改1、原来的不…

Tomcat-web服务器介绍以及安装部署

一、Tomcat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun和其他一些公司及个人共同开发而成。 Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用…

18类创新平台培育入库!长沙经开区2025年各类科技创新平台培育申报流程时间材料及申报条件

长沙经开区打算申报企业研发中心、技术创新中心、工程技术研究中心、新型研发机构、重点实验室、概念验证中心和中试平台、工程研究中心、企业技术中心、制造业创新中心、工业设计中心等创新平台的可先备案培育入库&#xff0c;2025年各类平台的认定将从培育库中优先推荐&#…

使用 Elasticsearch 进行集成测试初始化​​数据时的注意事项

作者&#xff1a;来自 Elastic piotrprz 在创建应该使用 Elasticsearch 进行搜索、数据聚合或 BM25/vector/search 的软件时&#xff0c;创建至少少量的集成测试至关重要。虽然 “模拟索引” 看起来很诱人&#xff0c;因为测试甚至可以在几分之一秒内运行&#xff0c;但它们实际…

9. Flink的性能优化

1. Flink的资源和代码优化 1.1 slot资源配置 Flink中具体跑任务的进程叫TaskManager&#xff0c;TM进程又会根据配置划分出诺干个TaskSlot&#xff0c;它是具体运行SubTask的地方。slot是Flink用来隔离各个subtask的资源集合&#xff0c;这里的资源一把指内存&#xff0c;TCP…

【文生图】windows 部署stable-diffusion-webui

windows 部署stable-diffusion-webui AUTOMATIC1111 stable-diffusion-webui Detailed feature showcase with images: 带图片的详细功能展示: Original txt2img and img2img modes 原始的 txt2img 和 img2img 模式 One click install and run script (but you still must i…

华为:Wireshark的OSPF抓包分析过程

一、OSPF 的5包7状态 5个数据包 1.Hello&#xff1a;发现、建立邻居&#xff08;邻接&#xff09;关系、维持、周期保活&#xff1b;存在全网唯一的RID&#xff0c;使用IP地址表示 2.DBD&#xff1a;本地的数据库的目录&#xff08;摘要&#xff09;&#xff0c;LSDB的目录&…