C++设计模式行为模式———迭代器模式

文章目录

  • 一、引言
  • 二、迭代器模式
  • 三、总结

一、引言

迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。C++标准库中内置了很多容器并提供了合适的迭代器,尽管我们不需要实现迭代器,但是需要了解迭代器的设计理念。


二、迭代器模式

我们设计一个固定大小数组作为容器,并实现一个迭代器。首先创建一个抽象迭代器:

template<class T>
class myIter{
public:virtual void First() = 0;virtual void Next() = 0;//指向下一个元素virtual bool IsDone() = 0;//是否遍历完virtual T& CurrentItem() = 0;//获取当前的元素virtual ~myIter() {}//作父类时析构函数应该为虚函数
};

上述迭代器仅有四个接口,这4个接口一般被认为是选代器应该实现的最小接口。当然,也可以根据实际需要,增加更多的接口。接着,创建一个抽象容器:

template<class T>
class myContainer{
public:
public:virtual myIter<T>* CreateIterator() = 0;//创建选代器virtual T& getItem(int index) = 0;//获取当前元素virtual int getSize() = 0;//容器中元素数量virtual ~myContainer() {}//作父类时析构函数应该为虚函数
};

从上面的代码中可以看到,为了支持所谓的多态迭代,在抽象容器类模板中定义了一个CreateIterator接口(成员函数),后续在具体的容器子类模板中,会在该接口中运用工厂模式创建相应的选代器。

template<class T>
class myVectorIter :public myIter<T>
{
public:myVectorIter(myContainer<T>*tmpc) :myvector(tmpc){m_current = 0;}virtual void First(){m_current = 0;//容器(数组)中的第一个元素下标为0}	virtual void Next(){m_current++;//下标+1,意味着数组中的下一个元素}virtual bool IsDone(){if (m_current >= myvector->getSize())return true;return false;}virtual T& CurrentItem(){return myvector->getItem(m_current);}
private:myContainer<T>* myvector;int m_current;//记录数组的当前下标(选代器在当前容器中的位置)
};

最后来一个具体的容器:

//具体容器类模板
template<typename T>
class myVector :public myContainer<T>{
public:myVector()//将数组中元素进行初始化{for (int i = 0; i < 10; ++i)m_elem[i] = i;}virtual myIter<T>* CreateIterator(){return new myVectorIter<T>(this);//要考虑在哪里释放的问题}virtual T& getItem(int index){return m_elem[index];}virtual int getSize(){return 10;//为简化代码,返回固定数字}
private://为了简化代码,将容器实现为固定装人10个元素的数组T m_elem[10];
};

在上述代码中,CreateIterator接口使用了工厂模式来创建一个具体的选代器,从而实现了多态选代(这意味着可以增加创建其他选代器的接口来支持不同的送代器,例如,再支持一个反向选代器来从最后一个元素向前遍历等)。

myContainer<int>* pcon = new myVector<int>();
myIter<int>* iter = pcon->CreateIterator();
for (iter->First(); !iter->IsDone(); iter->Next())
{cout << iter->CurrentItem() << endl;
}

代码可以看到,我们的迭代器完成了对容器的遍历。

在这里插入图片描述

迭代器模式一般包含四个角色:

  • 抽象迭代器Iterator):用于定义访问和遍历容器中的元素接口。
  • 具体迭代器ConcreteIterator):实现了抽象迭代器的接口,完成对聚合对象的元素遍历,记录当前元素的位置。
  • 抽象聚合Aggregate):将聚合理解为容器,用于存储和管理元素对象,声明一个CreateIterator方法用于创建一个迭代器对象,充当创建迭代器的工厂角色
  • 具体聚合ConcreteAggregate):实现了抽象的CreateIterator方法以创建相应的迭代器,该方法返回ConcreteAggregate的一个是适当的实例。

迭代器模式结构

在这里插入图片描述

迭代器模式做到了在不暴露内部结构的情况下,让外部代码透明地遍历(访问)其中包含元素的效果,另外值得一提的是,虽然不同的容器内部实现方式不同,但是通过迭代器来访问它们的方式却相同。

引入迭代器设计模式的定义:提供一种方法顺序访问一个聚合对象(容器)中各个元素,而又不暴露该对象的内部表示。

迭代器模式的核心思想就是把容器中对元素访问的代码放人迭代器中实现,与容器本身的功能代码相分离(容器是一个对象,迭代器是另一个对象),从而简化容器的设计。容器和迭代器之间彼此独立,从而使整个系统的设计更加灵活,可以定义不同的迭代器实现不同的遍历策略,例如常规迭代器、反向迭代器、const迭代器等都可以分别实现。


三、总结

当集合背后为复杂的数据结构, 且你希望对客户端隐藏其复杂性时 (出于使用便利性或安全性的考虑), 可以使用迭代器模式。迭代器封装了与复杂数据结构进行交互的细节, 为客户端提供多个访问集合元素的简单方法。 这种方式不仅对客户端来说非常方便, 而且能避免客户端在直接与集合交互时执行错误或有害的操作, 从而起到保护集合的作用。

使用方法:

  1. 声明迭代器接口。 该接口必须提供至少一个方法来获取集合中的下个元素。 但为了使用方便, 你还可以添加一些其他方法, 例如获取前一个元素、 记录当前位置和判断迭代是否已结束。
  2. 声明集合接口并描述一个获取迭代器的方法。 其返回值必须是迭代器接口。 如果你计划拥有多组不同的迭代器, 则可以声明多个类似的方法。
  3. 为希望使用迭代器进行遍历的集合实现具体迭代器类。 迭代器对象必须与单个集合实体链接。 链接关系通常通过迭代器的构造函数建立。
  4. 在你的集合类中实现集合接口。 其主要思想是针对特定集合为客户端代码提供创建迭代器的快捷方式。 集合对象必须将自身传递给迭代器的构造函数来创建两者之间的链接。
  5. 检查客户端代码, 使用迭代器替代所有集合遍历代码。 每当客户端需要遍历集合元素时都会获取一个新的迭代器。

我们可以使用迭代器模式来遍历组合模式。也可以使用工厂方法模式和迭代器来让子类返回不同的迭代器,并使得迭代器与集合相匹配。

身传递给迭代器的构造函数来创建两者之间的链接。
5. 检查客户端代码, 使用迭代器替代所有集合遍历代码。 每当客户端需要遍历集合元素时都会获取一个新的迭代器。

我们可以使用迭代器模式来遍历组合模式。也可以使用工厂方法模式和迭代器来让子类返回不同的迭代器,并使得迭代器与集合相匹配。

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

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

相关文章

智能体Agent调研

单个智能体建模与优化现状 人类长期以来追求类似于或超越人类水平的人工智能 (AI)&#xff0c;而 基于AI的代理&#xff08;Agent&#xff09;被认为是一个有前途的研究方向。传统计算机领域的Agent有多种&#xff0c;如自动化脚本、网络爬虫、推荐系统、软件机器人能够独立自…

SAP PI/PO Proxy2JDBC SQL_QUERY动态接口示例

目录 背景&#xff1a; 完整demo步骤&#xff1a; IR: ID: SPROXY: 测试代码&#xff1a; 注意点&#xff1a; 背景&#xff1a; 中途临时帮客户项目做其他功能&#xff0c;项目上有部分开发项需要通过PO去第三方数据库取数&#xff0c;项目上的开发对PO不太熟&#xf…

【汇编语言】数据处理的两个基本问题(三) —— 汇编语言的艺术:从div,dd,dup到结构化数据的访问

文章目录 前言1. div指令1.1 使用div时的注意事项1.2 使用格式1.3 多种内存单元表示方法进行举例1.4 问题一1.5 问题一的分析与求解1.5.1 分析1.5.2 程序实现 1.6 问题二1.7 问题二的分析与求解1.7.1 分析1.7.2 程序实现 2. 伪指令 dd2.1 什么是dd&#xff1f;2.2 问题三2.3 问…

模型的评估指标——IoU、混淆矩阵、Precision、Recall、P-R曲线、F1-score、mAP、AP、AUC-ROC

文章目录 预测框的预测指标——IoU&#xff08;交并比&#xff09;分类预测指标混淆矩阵&#xff08;Confusion Matrix&#xff0c;TP、FP、FN、TN)Precision&#xff08;精度&#xff09;Recall&#xff08;召回率&#xff09;P-R曲线F1-scoreTPR、TNR、FPR、FNRROC曲线下面积…

轻量云服务器:入门级云计算的最佳选择

在云计算领域&#xff0c;轻量云服务器逐渐成为小型企业、个人开发者和初创公司关注的热点。它凭借高性价比、简单易用和稳定性能&#xff0c;正在改变传统的服务器部署方式。本文将详细解析轻量云服务器的定义、优势、适用场景及如何选择最佳方案&#xff0c;帮助您全面了解这…

【初阶数据结构篇】归并排序、计数排序

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

移远通信5G RedCap模组RG255C-CN通过中国电信5G Inside终端生态认证

近日&#xff0c;移远通信5G RedCap模组RG255C-CN荣获中国电信颁发的5G Inside终端生态认证证书。这表明&#xff0c;该产品在5G基本性能、网络兼容性、安全特性等方面已经过严格评测且表现优异&#xff0c;将进一步加速推动5G行业终端规模化应用。 中国电信5G Inside终端生态认…

Towards Reasoning in Large Language Models: A Survey

文章目录 题目摘要引言什么是推理?走向大型语言模型中的推理测量大型语言模型中的推理发现与启示反思、讨论和未来方向 为什么要推理?结论题目 大型语言模型中的推理:一项调查 论文地址:https://arxiv.org/abs/2212.10403 项目地址: https://github.com/jeffhj/LM-reason…

Android Studio | 修改镜像地址为阿里云镜像地址,启动App

在项目文件的目录下的 settings.gradle.kts 中修改配置&#xff0c;配置中包含插件和依赖项 pluginManagement {repositories {maven { urluri ("https://www.jitpack.io")}maven { urluri ("https://maven.aliyun.com/repository/releases")}maven { urlu…

Python | Leetcode Python题解之第564题数组嵌套

题目&#xff1a; 题解&#xff1a; class Solution:def arrayNesting(self, nums: List[int]) -> int:ans, n 0, len(nums)for i in range(n):cnt 0while nums[i] < n:num nums[i]nums[i] ni numcnt 1ans max(ans, cnt)return ans

2024-11-17 -MATLAB三维绘图简单实例

1. x -1:0.05:1; y x; [X, Y] meshgrid(x, y); f (X, Y) (sin(pi * X) .* sin(pi * Y)) .^ 2.*sin(2.*X2.*Y); mesh(X, Y, f(X, Y)); % 调用函数f并传递X和Y xlabel(X-axis); ylabel(Y-axis); zlabel(Z-axis); title(Surface Plot of (sin(pi * X) .* sin(pi * Y)) .^ 2.*…

网络层9——虚拟专用网VPN和网络地址转换NAT

目录 一、为什么有虚拟专用网&#xff1f; 二、如何理解“虚拟专用网”&#xff1f; 三、IP隧道技术实现虚拟专用网 四、网络地址变换 一、为什么有虚拟专用网&#xff1f; 第一&#xff0c;IPv4只有32位&#xff0c;最多有40亿个全球唯一的IP地址数量不够&#xff0c;无法…

小程序如何完成订阅

小程序如何完成订阅 参考相关文档实践问题处理授权弹窗不再触发引导用户重新授权 参考相关文档 微信小程序实现订阅消息推送的实现步骤 发送订阅消息 小程序订阅消息&#xff08;用户通过弹窗订阅&#xff09;开发指南 实践 我们需要先选这一个模板&#xff0c;具体流程参考…

Oracle OCP认证考试考点详解082系列19

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 91. 第91题&#xff1a; 题目 解析及答案&#xff1a; 关于 Oracle 数据库中的索引及其管理&#xff0c;以下哪三个陈述是正确的&#x…

HuggingFace:基于YOLOv8的人脸检测模型

个人操作经验总结 1、YOLO的环境配置 github 不论base环境版本如何&#xff0c;建议在conda的虚拟环境中安装 1.1、创建虚拟环境 conda create -n yolov8-face python3.9conda create &#xff1a;创建conda虚拟环境&#xff0c; -n &#xff1a;给虚拟环境命名的…

2024-11-15 Element-ui的tab切换中table自适应宽度无法立即100%的问题

前言 今天在写一个统计图表的时候&#xff0c;将所有的table表格和echarts图表放到一个页面中&#xff0c;这样会在纵向上出现滚动条&#xff0c;上下滑动对用户体验不好&#xff0c;于是改成tab切换的形式 遇到的问题 正如标题所述&#xff0c;elementui在tab中使用table时&…

【汇编】c++游戏开发

由一起学编程创作的‘C/C项目实战&#xff1a;2D射击游戏开发&#xff08;简易版&#xff09;&#xff0c; 440 行源码分享来啦~’&#xff1a; C/C项目实战&#xff1a;2D射击游戏开发&#xff08;简易版&#xff09;&#xff0c; 440 行源码分享来啦~_射击c-CSDN博客文章浏览…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

k-近邻算法(K-Nearest Neighbors, KNN)详解:机器学习中的经典算法

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url&#xff0c;选择自己的项目路径 3、点击Clone&#xff0c;就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支&#xff08;非必要可以不使用&#xf…