C++实现设计模式---迭代器模式 (Iterator)
迭代器模式 (Iterator)
迭代器模式 是一种行为型设计模式,它提供了一种方法,顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
意图
- 提供一种方法,可以顺序访问一个容器对象中的元素,而无需暴露其内部实现。
- 将遍历行为从集合对象中分离出来,使得遍历行为可以独立变化。
使用场景
- 需要顺序访问一个聚合对象中的元素:
- 如数组、链表或集合。
- 需要支持多种遍历方式:
- 如正序遍历、反序遍历等。
- 需要解耦遍历算法和容器实现:
- 容器的内部结构可能经常变化,但不希望影响遍历逻辑。
参与者角色
- 迭代器接口 (Iterator)
- 定义用于访问聚合对象元素的方法。
- 具体迭代器 (ConcreteIterator)
- 实现迭代器接口,提供对聚合对象的具体遍历。
- 聚合接口 (Aggregate)
- 定义创建迭代器的方法。
- 具体聚合类 (ConcreteAggregate)
- 实现聚合接口,提供一个数据集合并创建相应的迭代器。
示例代码
以下代码展示了迭代器模式的实现,用于模拟对一个数字集合的顺序访问。
#include <iostream>
#include <vector>
#include <memory>// 迭代器接口
template <typename T>
class Iterator {
public:virtual ~Iterator() = default;// 获取下一个元素virtual T next() = 0;// 判断是否还有下一个元素virtual bool hasNext() const = 0;
};// 聚合接口
template <typename T>
class Aggregate {
public:virtual ~Aggregate() = default;// 创建迭代器virtual std::unique_ptr<Iterator<T>> createIterator() const = 0;
};// 具体迭代器
template <typename T>
class ConcreteIterator : public Iterator<T> {
private:const std::vector<T>& collection; // 引用聚合对象size_t index; // 当前索引public:explicit ConcreteIterator(const std::vector<T>& collection): collection(collection), index(0) {}T next() override {return collection[index++];}bool hasNext() const override {return index < collection.size();}
};// 具体聚合类
template <typename T>
class ConcreteAggregate : public Aggregate<T> {
private:std::vector<T> collection; // 存储元素的集合public:void add(const T& element) {collection.push_back(element);}std::unique_ptr<Iterator<T>> createIterator() const override {return std::make_unique<ConcreteIterator<T>>(collection);}
};// 客户端代码
int main() {// 创建一个具体聚合对象ConcreteAggregate<int> aggregate;aggregate.add(1);aggregate.add(2);aggregate.add(3);aggregate.add(4);aggregate.add(5);// 获取迭代器auto iterator = aggregate.createIterator();// 遍历聚合对象std::cout << "集合中的元素: ";while (iterator->hasNext()) {std::cout << iterator->next() << " ";}std::cout << "
";return 0;
}
代码解析
1. 迭代器接口 (Iterator)
- 定义了
next和hasNext方法,用于访问聚合对象中的元素。 - 子类需要实现这些方法以提供具体的遍历逻辑。
template <typename T>
class Iterator {
public:virtual ~Iterator() = default;virtual T next() = 0;virtual bool hasNext() const = 0;
};
2. 具体迭代器 (ConcreteIterator)
- 实现了迭代器接口。
- 使用内部索引
index记录当前遍历的位置,并提供next和hasNext方法。
template <typename T>
class ConcreteIterator : public Iterator<T> {
private:const std::vector<T>& collection;size_t index;
public:explicit ConcreteIterator(const std::vector<T>& collection): collection(collection), index(0) {}T next() override { return collection[index++]; }bool hasNext() const override { return index < collection.size(); }
};
3. 聚合接口 (Aggregate)
- 定义了
createIterator方法,用于创建迭代器。
template <typename T>
class Aggregate {
public:virtual ~Aggregate() = default;virtual std::unique_ptr<Iterator<T>> createIterator() const = 0;
};
4. 具体聚合类 (ConcreteAggregate)
- 存储数据集合,并实现了
createIterator方法,返回具体的迭代器实例。
template <typename T>
class ConcreteAggregate : public Aggregate<T> {
private:std::vector<T> collection;
public:void add(const T& element) { collection.push_back(element); }std::unique_ptr<Iterator<T>> createIterator() const override {return std::make_unique<ConcreteIterator<T>>(collection);}
};
5. 客户端代码
- 客户端通过聚合对象获取迭代器,并通过迭代器访问集合中的元素。
int main() {ConcreteAggregate<int> aggregate;aggregate.add(1);aggregate.add(2);aggregate.add(3);auto iterator = aggregate.createIterator();while (iterator->hasNext()) {std::cout << iterator->next() << " ";}
}
优缺点
优点
- 统一遍历接口:
- 提供了统一的遍历接口,客户端无需了解容器的具体实现。
- 解耦遍历算法和容器实现:
- 容器的内部结构可以改变,而不影响遍历逻辑。
- 支持多种遍历方式:
- 可以为同一个容器实现多种迭代器,支持不同的遍历方式。
缺点
- 类数量增加:
- 每种容器需要实现对应的迭代器类。
- 遍历效率可能降低:
- 相比直接访问容器元素,使用迭代器可能增加额外的开销。
适用场景
- 需要顺序访问聚合对象中的元素:
- 如遍历集合、列表或数组。
- 需要支持多种遍历方式:
- 希望为容器实现不同的遍历逻辑。
- 希望解耦遍历算法和容器实现:
- 通过迭代器封装遍历逻辑,避免依赖容器的内部实现。
总结
迭代器模式通过将遍历逻辑封装到迭代器中,实现了聚合对象与遍历算法的解耦。它特别适用于需要顺序访问容器元素,同时希望支持多种遍历方式的场景。
相关文章:
C++实现设计模式---迭代器模式 (Iterator)
迭代器模式 (Iterator) 迭代器模式 是一种行为型设计模式,它提供了一种方法,顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 意图 提供一种方法,可以顺序访问一个容器对象中的元素,而无需暴露其…...
海康工业相机的应用部署不是简简单单!?
作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 笔者使用的设备及环境:WSL2-Ubuntu22.04MV-CS016-10UC 不会吧?不会吧?不会还有人拿到海康工业相机还是一脸懵叭?不会还有人…...
Windows电脑安装File Browser与cpolar轻松搭建本地云盘
文章目录 前言1.下载安装File Browser2.启动访问File Browser3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 无论是个人用户还是企业团队,都希望能够有一个高效、安全的解决方案来…...
mac配置 iTerm2 使用lrzsz与服务器传输文件
mac配置 1. 安装支持rz和sz命令的lrzsz brew install lrzsz2. 下载iterm2-send-zmodem.sh和iterm2-recv-zmodem.sh两个脚本 # 克隆仓库 git clone https://github.com/aikuyun/iterm2-zmodem ~/iterm2-zmodem# 进入到仓库目录 cd ~/iterm2-zmodem# 设置脚本文件可执行权限 c…...
【HBuilderX 中 Git 的使用】
目录: 一:安装必要的版本控制工具二:把Github上的项目克隆到本地三:将本地的项目上传到Github上 一:安装必要的版本控制工具 1️⃣ 安装 TortoiseGit 工具,下载地址:https://tortoisegit.org/do…...
Golang结合MySQL和DuckDB提高查询性能
要在Golang中组合MySQL和DuckDB以提高查询性能,请考虑使用混合查询执行方法。这种方法利用了MySQL强大的事务管理和DuckDB闪电般的分析处理能力。本文介绍如何充分利用两者的方法。 各取所长 用MySQL处理事务,用DuckDB处理分析 MySQL应该处理常规的INS…...
学技术学英语:TCP的三次握手和四次挥手
单词 汉语意思 音标 acknowledge 承认,确认 /əkˈnɒl.ɪdʒ/ acknowledgment 确认,承认 /əkˈnɒl.ɪdʒ.mənt/ duplex 双向的 /ˈdjuː.pleks/ establish 建立 /ɪˈstb.lɪʃ/ handshake 握手,握手协议 /ˈhnd.ʃeɪk…...
xiao esp32 S3播放SD卡wav音频
本文旨在使用xiao esp32 S3 播放SD卡上的音频文件 1 硬件准备 SD卡 2 代码实现 2.1 依赖库 ESP32-audioI2S-master 2.2 代码 #include "Arduino.h" #include "Audio.h" #include "SD.h"// Digital I/O used #define I2S_DOUT 6 #defi…...
Unity中实现伤害跳字效果(简单好抄)
第一步骤安装并导入Dotween插件(也可以不用导入之后直接下载我的安装包) 官网DOTween - 下载 第二步: 制作跳字预制体 建议把最佳适应打开,这样就不怕数字太大显示不全了。 第三步:创建一个空对象并编写脚本JumpNumbe…...
GaussDB日常维护操作
GaussDB日常维护操作 日常维护检查操作系统参数数据库健康状态日志收集日志清理应用连接数表的例行维护索引重建慢SQL诊断 日常维护检查 实例状态检查: #检查集群实例状态 gs_check -U omm -i CheckClusterStatecm_ctl query -Cvipd#检查主备DN的角色和同步状态 g…...
redis实现限流
令牌桶逻辑 计算逻辑: 代码: import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool;/*** ClassName RedisRateLimiterTokenBucket* Description TODO* Author zhang zhengdong* DATE 2025/1/17 20:22* Version 1.0*/ public class…...
基于SpringBoot和PostGIS的各国及所属机场信息检索及可视化实现
目录 前言 一、空间数据简介 1、全球国家信息表 2、机场信息表 3、国家机场检索实现 二、SpringBoot后台实现 1、模型层实现 2、控制层实现 三、WebGIS可视化实现 1、Leaflet界面实现 2、国家及其机场可视化成果 3、全球机场数量排行榜 四、总结 前言 新春佳节即将…...
python http server运行Angular 单页面路由时重定向,解决404问题
问题 当Angular在本地ng server运行时候,可以顺利访问各级路由。 但是运行ng build后,在dist 路径下的打包好的额index.html 必须要在服务器下运行才能加载。 在服务器下我们第一次访问路由页面时是没有问题的,但是尝试刷新页面或手动输入路…...
GPT-4o背后的语音技术
GPT-4o背后的语音技术 GPT-4o是一个any2any的多模态模型,能够接受文本、音频、图像、视频等多模态输入,也能够生成包含文本、语音、图像和视频等混合内容的多模态输出。本文主要谈语音多模态的实现,并分享一些对于语音研究未来发展的看法。 GPT-4o (“o” 代表 “omni”) …...
微透镜阵列精准全检,白光干涉3D自动量测方案提效70%
广泛应用的微透镜阵列 微透镜是一种常见的微光学元件,通过设计微透镜,可对入射光进行扩散、光束整形、光线均分、光学聚焦、集成成像等调制,进而实现许多传统光学元器件难以实现的特殊功能。 微透镜阵列(Microlens Array&#x…...
Spring boot框架下的RocketMQ消息中间件
1. RocketMQ 基础概念 1.1 核心概念 以下是 RocketMQ 核心概念在 Spring Boot 的 Java 后端代码中的实际使用方式: Producer(生产者) 定义:Producer 是负责发送消息到 RocketMQ 的组件。它可以将消息发送到指定的 Topic。 实…...
记录一次 centos 启动失败
文章目录 现场1分析1现场2分析2搜索实际解决过程 现场1 一次断电,导致 之前能正常启动的centos 7.7 起不来了有部分log , 关键信息如下 [1.332724] XFS(sda3): Internal error xfs ... at line xxx of fs/xfs/xfs_trans.c [1.332724] XFS(sda3): Corruption of in-memory data…...
C++学习第五天
创作过程中难免有不足,若您发现本文内容有误,恳请不吝赐教。 提示:以下是本篇文章正文内容,下面案例可供参考 一、构造函数 问题1 关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下…...
openharmony标准系统方案之瑞芯微RK3568移植案例
标准系统方案之瑞芯微RK3568移植案例 本文章是基于瑞芯微RK3568芯片的DAYU200开发板,进行标准系统相关功能的移植,主要包括产品配置添加,内核启动、升级,音频ADM化,Camera,TP,LCD,…...
深入理解 SSH 端口转发:本地 vs 远程 vs 动态转发
🌟 简介 SSH 端口转发(SSH Port Forwarding)作为一种强大而灵活的技术,不仅可以帮助我们安全地访问远程服务,还能轻松突破网络限制。本文将带你深入了解 SSH 端口转发的原理、类型和实战应用。 🌈 目录 &a…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
