**20.迭代器模式(Iterator)

news2024/11/25 2:24:27

意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

上下文:集合对象内部结构常常变化各异。对于这些集合对象,能否在不暴露其内部结构的同时,让外部Client透明地访问其中包含的元素,同时让这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供可能?

UML

在这里插入图片描述

Iterator:定义访问和遍历元素的接口(.NET中定义了标准的IEnumrator接口)。ConcreteIterator:实现Iterator接口,同时在对Aggregate遍历时跟踪当前的位置。Aggregate:定义创建相应Iterator对象的接口(.NET中定义了标准的IEnumrable接口)。ConcreteAggregate:实现创建相应Iterator对象的接口,该操作返回一个适当的ConcreteIterator实例。

注意:.NET中的foreach关键字在编译时会自动创建迭代器对象,并使用该对象对集合进行遍历。.NET中的yield return关键字使得定义迭代器对象更加容易。

代码

#include <iostream>
#include <list>
#include <array>
#include <vector>
using namespace std;
 
//Iterator迭代器抽象类
class Iterator
{
public:
    virtual void* First() = 0;
    virtual void* Next() = 0;
    virtual bool IsDone() = 0;
    virtual void* CurrentItem() = 0;
};
 
//Aggregate聚集抽象类
class Aggregate
{
public:
    virtual Iterator *CreateIterator() = 0;
};
 
//ConcreteAggregate具体聚集类 继承Aggregate
class ConcreteAggregate:public Aggregate
{
public:
    vector<void*> items;
    // Aggregate interface
public:
    Iterator *CreateIterator();
    int getCount() const;
    //既可以作为左值,也可以作为又值
    void** operator[](unsigned int index){
        if(items.size() <= index){
            items.resize(index+1);
        }
        return &items[index];
    }
};
 
class ConcreteIterator:public Iterator
{
public:
    ConcreteAggregate *ca;
    int current;
    ConcreteIterator(ConcreteAggregate *c):ca(c){
        this->current = 0;
    }
    virtual void* First();
    virtual void* Next();
    virtual bool IsDone();
    virtual void* CurrentItem();
};
 
Iterator *ConcreteAggregate::CreateIterator()
{
    return new ConcreteIterator(this);
}
 
int ConcreteAggregate::getCount() const
{
    return items.size();
}
 
void *ConcreteIterator::First()
{
    return *(*ca)[0];
}
 
void *ConcreteIterator::Next()
{
    if(current < ca->getCount()){
        current++;
    }
    if(current < ca->getCount()){
        return *(*ca)[current];
    }
    return nullptr;
}
 
bool ConcreteIterator::IsDone()
{
    return current >= ca->getCount()?true:false;
}
 
void *ConcreteIterator::CurrentItem()
{
    return *(*ca)[current];
}
 
class ConcreteIteratorDesc:public Iterator
{
public:
    ConcreteAggregate *ca;
    int current;
    ConcreteIteratorDesc(ConcreteAggregate *c):ca(c){
        this->current = c->getCount() - 1;
    }
    virtual void* First();
    virtual void* Next();
    virtual bool IsDone();
    virtual void* CurrentItem();
};
void *ConcreteIteratorDesc::First()
{
    if(ca->getCount() == 0){
        return nullptr;
    }
    return *(*ca)[ca->getCount() - 1];
}
 
void *ConcreteIteratorDesc::Next()
{
    if(current >= 0){
        current--;
    }
    if(current >= 0){
        return *(*ca)[current];
    }
    return nullptr;
}
 
bool ConcreteIteratorDesc::IsDone()
{
    return current < 0?true:false;
}
void *ConcreteIteratorDesc::CurrentItem()
{
    return *(*ca)[current];
}
int main()
{
    ConcreteAggregate ca;
    *(ca[0]) = (void*)5;
    *ca[1] = (void*)10;
    *ca[2] = (void*)15;
    *ca[3] = (void*)20;
//    cout << (int) *ca[0] << endl;
//    cout << (int) *ca[1] << endl;
//    cout << ca.getCount() << endl;
 
    Iterator *i = new ConcreteIterator(&ca);
 
    cout << "开始遍历" << endl;
    while(!i->IsDone()){
        cout << (int)i->CurrentItem() << endl;
        i->Next();
    }
 
    Iterator *i_desc = new ConcreteIteratorDesc(&ca);
 
    cout << "开始反向遍历" << endl;
    while(!i_desc->IsDone()){
        cout << (int)i_desc->CurrentItem() << endl;
        i_desc->Next();
    }
    cout << "--end--" << endl;
    return 0;
}

结果:

开始遍历
5
10
15
20
开始反向遍历
20
15
10
5
--end--

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

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

相关文章

大数据+大模型的尽头——数据分析师的未来会怎样?

大数据大模型的尽头一定是干掉数据分析师吗&#xff1f; | 近匠

12:STM32---RTC实时时钟

目录 一:时间相关 1:Unix时间戳 2: UTC/GMT 3:时间戳转化 二:BKP 1:简历 2:基本结构 三: RTC 1:简历 2: 框图 3:RTC基本结构 4:RTC操作注意 四:案例 A:读写备份寄存器 1:连接图 2: 步骤 3: 代码 B:实时时钟 1:连接图 2:函数介绍 3:代码 一:时间相关 1:Un…

如何与Linamar Corp 建立EDI连接?

Linamar Corp&#xff08;以下简称Linamar&#xff09;是一家全球领先的汽车零部件制造商&#xff0c;总部位于加拿大。随着业务的不断扩展&#xff0c;Linamar 需要与其供应商、分销商和合作伙伴之间实现更高效的业务交流和数据共享。为了提高业务流程的自动化水平&#xff0c…

1.虚拟机无法连接网络,且无法ping通的问题解决

1.介绍 今天操作Jedis连接虚拟机的redis数据库时&#xff0c;连接不上&#xff0c;找了很多解决方案&#xff0c;都解决不了&#xff0c;最后发现是虚拟机的配置问题&#xff0c;虚拟机无法连接网络&#xff0c;且没有设置本机ip地址&#xff0c;所以ifconfig的根本就查不出ip…

C++之智能指针类型转换应用总结(二百二十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

数据结构:线性表之-队列

目录 什么是队列&#xff1f; 详解&#xff1a; 功能介绍 代码实现 定义队列基本结构 1&#xff0c;初始化 2, 销毁 3,尾入数据 4,头出数据 5,取队头的数据 6,取队尾的数据 7,判断是否为空 8,计算队列中的元素 成品 Queue.h Queue.c test.c 队列的讲解将建立在…

Oracle使用遇到的问题

一、Navicat 连接Orcle提示 Oracle library is not loaded 1.前往官网下载客户端 http://www.oracle.com/technetwork/database/database-technologies/instant-client/downloads/index.html 2.选择与系统匹配的“Instant Client”和sqlpus。

App的专项测试

文章目录 App的专项测试都从哪个方面测试安装和卸载版本升级消息推送弱网测试兼容性测试交互性测试 App的专项测试都从哪个方面测试 在APP测试过程中&#xff0c;除了功能测试外&#xff0c;还需要进行一些专项测试来发现更为深层的问题&#xff0c;这些问题主要是针对某个特殊…

时空智友企业流程化管控系统文件存在任意文件上传漏洞 附POC

、 文章目录 时空智友企业流程化管控系统文件存在任意文件上传漏洞 附POC1. 时空智友企业流程化管控系统文件简介2.漏洞描述3.影响版本4.fofa查询语句5.漏洞复现6.POC&EXP7.整改意见8.往期回顾 时空智友企业流程化管控系统文件存在任意文件上传漏洞 附POC 免责声明&#…

【Redis】深入探索 Redis 的哨兵(Sentinel)机制原理,基于 Docker 模拟搭建 Redis 主从结构和哨兵分布式架构

文章目录 一、对 Redis Sentinel 的认识1.1 什么是 Redis Sentinel1.2 为什么要使用 Redis Sentinel1.2.1 主从复制问题1.2.2 人工恢复主节点故障 二、Redis Sentinel 原理剖析2.1 Redis Sentinel 架构2.2 Raft 算法和领袖节点2.3 哨兵节点2.4 故障检测2.5 故障切换2.6 监控和通…

Android调用相册并展示选中的图片

调用相册 //定义请求码int PICK_PHOTO_REQUEST 1234;int RESULT_CANCELED 0;//定义取消码//触发监听后调用相册findViewById(R.id.image_gallery).setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//创建一个意图并开启startActivi…

Visual Studio 2017 安装

C自学精简实践教程 目录(必读) 这篇文章会保证你第一次安装VS2017就成功运行Hello World! 下载Visual Studio Installer Gitee 下载 VS2017/vs2017_Community.exe CalmReason/VisualStudio - 码云 - 开源中国 (gitee.com) 百度云下载 链接&#xff1a;https://pan.baidu…

ArangoDB关键知识点汇总大全(不定时更新)

二、ArangoDB数据模型与索引 2.1 数据模型 ArangoDB的数据模型分为数据库(databse)、集合(collection)、文档(document)&#xff0c;分别与RDBMS中的数据库、表、行对应。 数据类型包括&#xff1a;string、boolean、number、array、document/object Collection&#xff1a…

【详细图文】Windows下安装RustRover和配置Rust环境

前言 Rust已经火了挺长时间了&#xff0c;连微软的Windows内核都用它来重新改写&#xff0c;可想而知其厉害之处。之前有看过Rust的教程&#xff0c;但一直没有去尝试。今天看到JetBrains出了Rust 专用的IDE&#xff1a;RustRover。作为JetBrains的粉丝&#xff0c;决定进行一…

【强化学习】02—— 探索与利用

文章目录 1. 探索与利用2. 探索策略3. 多臂老虎机3.1. 形式化描述3.2. 估计期望奖励3.3. 懊悔regret函数 4. 贪心策略和 ϵ − g r e e d y \epsilon-greedy ϵ−greedy策略5. 积极初始化6. 显示地考虑动作的价值分布7. UCB上置信界算法8. 汤普森采样算法总结参考 1. 探索与利用…

Hive 的权限管理

目录 ​编辑 一、Hive权限简介 1.1 hive中的用户与组 1.1.1 用户 1.1.2 组 1.1.3 角色 1.2 使用场景 1.2.1 hive cli 1.2.2 hiveserver2 1.2.3 hcatalog api 1.3 权限模型 1.3.1 Storage Based Authorization in the Metastore Server 1.3.2 SQL Standards Based …

【Vue.js】vue-cli搭建SPA项目并实现路由与嵌套路由---详细讲解

一&#xff0c;何为SPA SPA&#xff08;Single Page Application&#xff09;是一种 Web 应用程序的开发模式&#xff0c;它通过使用 AJAX 技术从服务器异步加载数据&#xff0c;动态地更新页面内容&#xff0c;实现在同一个页面内切换不同的视图&#xff0c;而无需整页刷新 1.…

部署Kafka

kafka&#xff1a;kafka_2.13-3.5.1 NOTE: Your local environment must have Java 8 installed. Apache Kafka can be started using ZooKeeper or KRaft. To get started with either configuration follow one the sections below but not both. 1 Windows单机 1.1 Kafka w…

wx.canvasToTempFilePath导出的图片不清晰

使用wx.canvasToTempFilePath接口&#xff0c;导出的canvas图片在手机上看不清晰 解决办法&#xff1a;本质上就是生成一个更大的图片&#xff0c;因为手机的屏幕设备的像素比现在一般都是超过2的。实际上我们只需要在使用wx.canvasToTempFilePath的时候&#xff0c;设置参数d…

LabVIEW在运行时调整表控件列宽

LabVIEW在运行时调整表控件列宽 如何在LabIEW中运行时调整表控件的列宽大小&#xff1f; 在VI运行时&#xff0c;有两种不同的方法可以更改表中列的宽度。首先&#xff0c;可以使用鼠标手动更改它们;其次&#xff0c;可以从框图中以编程方式更改它们。 手动更改列宽 只有在…