C++实现对象行为型-迭代器模式

news2024/11/27 8:47:32

1.1 基本概念

迭代器模式(Iterator Pattern):提供了一种方法来访问聚合对象,而不用暴露这个对象的内部。

聚合对象的两个基本功能:

(1)存储内部数据;

(2)遍历内部数据;

1.2 模式结构

 (1)Iterator(抽象迭代器)

抽象迭代器定义了访问和变量 元素的接口,用于获取第一个元素的first(),访问下一个元素的next(),用于获取当前元素的current()。

 (2)ConcreteIterator(具体迭代器)

具体迭代器实现了抽象迭代器接口,完成对聚合对象的遍历,同时在对聚合进行遍历时跟踪其当前位置

(3)Aggregate(抽象聚合类或称抽象容器)

抽象聚合类用于存储对象,并定义创建相应迭代器对象的接口,声明一个 createIterator() 方法,用于创建一个迭代器对象。

(4)ConcreteAggregate(具体聚合类或称具体容器)

具体聚合类实现了创建相应迭代器的接口,实现了在聚合类中声明的 createIterator() 方法,该方法返回一个对应的具体迭代器实例。

  1. 容器部分,内部可以存放一系列数据,并提供迭代器调用接口。
  2. 迭代器部分,内部含有对容器部分的调用,并获得容器内部提供的方法。

具体容器和具体迭代器两者是相互调用的,也就是说容器调用了迭代器,然后通过迭代器调用了容器内部自身的方法来实现封装。

1.3 优缺点

优点:

(1)支持以不同的方式遍历一个聚合对象。迭代器可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。同时其封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心

(2)在迭代器模式中,增加新的聚合类和迭代器都很方便,不需要修改原有代码,满足开闭原则;

缺点:

由于存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,一定程度上增加了系统的复杂性。

1.4 应用场景

(1)访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时,无须了解其内部实现细节;

(2)需要为聚合对象提供多种遍历方式;

(3)为遍历不同的聚合结构提供一个统一的接口。

1.5 举例

电视机遥控器可以看做一个迭代器实例,电视机遥控器可以实现对电视机频道集合的遍历操作。

#include<iostream>
#include <vector>
#include <string>
// 具体处理者 Department manager

using namespace std;
#define SAFE_DELETE(p) if (p) { delete p; p = NULL; }

/**
* @brief TVIterator 电视机遥控器类
* @brief (抽象迭代器类) 声明迭代器所具有的方法
*/
class TVIterator
{
public:
    TVIterator(){};
    virtual ~TVIterator(){};
    virtual string First() = 0;
    virtual string Next() = 0;
    virtual string GetCur() = 0;
    virtual bool IsEnd() = 0;
};

/**
* @brief TelevisionAggregate 电视机类
* @brief 抽象聚合类 声明用于创建 具体迭代器对象的CreateIterator() 方法
*/
class TelevisionAggregate
{
public:
 TelevisionAggregate(){};
    virtual ~TelevisionAggregate(){};
    virtual int Count() = 0;
    virtual void Push(const string &strValue) = 0;
    virtual string Pop(const int index) = 0;
    virtual TVIterator *CreateIterator() = 0;
};

/**
* @brief TclTVIterator 具体聚合类
* @brief 具体迭代器类
*/
class TclTVIterator : public TVIterator
{
public:
 TclTVIterator(TelevisionAggregate *pAggregate) : TVIterator()
    {
        m_nCurrent = 0;
        m_Aggregate = pAggregate;
    }

    string First()
    {
        return m_Aggregate->Pop(0);
    }
string Next()
    {
        string strRet;
        m_nCurrent++;

        if(m_nCurrent < m_Aggregate->Count())
        {
            strRet = m_Aggregate->Pop(m_nCurrent);
        }

        return strRet;
    }

string GetCur()
    {
        return m_Aggregate->Pop(m_nCurrent);
    }

    bool IsEnd()
    {
        return ((m_nCurrent >= m_Aggregate->Count()) ? true : false);
    }

private:
    int m_nCurrent;
    TelevisionAggregate *m_Aggregate;
};

/**
* @brief TclTelevisionAggregate TCL电视机类
* @brief 具体聚合类
*/
class TclTelevisionAggregate : public TelevisionAggregate
{
public:
TclTelevisionAggregate() : m_pIterator(NULL)
    {
        m_vecItems.clear();
    }

    ~TclTelevisionAggregate()
    {
        if(m_pIterator != NULL)
        {
            delete m_pIterator;
            m_pIterator = NULL;
        }
    }
 TVIterator *CreateIterator()
    {
        if(m_pIterator == NULL)
        {
            m_pIterator = new TclTVIterator(this);
        }

        return m_pIterator;
    }

 int Count()
    {
        return m_vecItems.size();
    }

    void Push(const string &strValue)
    {
        m_vecItems.push_back(strValue);
    }

    string Pop(const int index)
    {
        string strRet;

        if(index < Count())
        {
            strRet = m_vecItems[index];
        }

        return strRet;
    }

private:
    TVIterator *m_pIterator;
    vector<string> m_vecItems;
};

int main(int argc, char **argv)
{
    TclTelevisionAggregate *pTclTelevision = new TclTelevisionAggregate();
    if(pTclTelevision == NULL)
        return -1;

    pTclTelevision->Push("CCTV-1");
    pTclTelevision->Push("CCTV-2");
    pTclTelevision->Push("CCTV-3");
TVIterator *iter = NULL;
    iter = pTclTelevision->CreateIterator();

    if(iter != NULL)
{
        string strItem = iter->First();

        while(!iter->IsEnd())
        {
            cout << iter->GetCur() << " is ok" << endl;
            iter->Next();
        }
    }

SAFE_DELETE(pTclTelevision);
	//SAFE_DELETE(iter);

    return 0;
}

参考文献:

【1】C++之迭代器(Iterator)模式 - 古月居

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

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

相关文章

MySQL表的进阶知识

目录 一、数据库约束 1、not null 2、unique 3、primary key 4、auto_increment 5、default 6、foreign key 7、check 二、插入数据 三、设计表 1、一对一 2、一对多 3、多对多 四、查询 1、聚合查询 a、聚合函数查询 b、group by c、having 2、联合查…

pikachu靶场-8 越权漏洞

越权漏洞 越权漏洞概述 由于没有对用户权限进行严格的判断&#xff0c;导致低权限的账号&#xff08;比如普通用户&#xff09;可以去完成高权限账号&#xff08;比如超级管理员&#xff09;范围内的操作 平行越权&#xff1a;A用户和B用户属于同一级别用户&#xff0c;但各…

虚拟主播怎么做出来的?今日安利:AI虚拟人物怎么弄?

某天&#xff0c;一位品牌店的老板向我寻求帮助&#xff0c;大概内容就是&#xff1a;“他最近要开拓线上店铺的直播渠道&#xff0c;直播时间较长&#xff0c;雇一位主播又费钱又辛苦&#xff0c;想制作一个符合品牌调性的AI虚拟人物来带货。”于是我跟他分享了制作虚拟主播的…

北京医保定点医院2022年版

文章目录概述官方查询方法49家A类定点医院政府公告初始19家2021年4月新增13家A类医院2021年11月新增7家A类医院2022年6月新增10家A类医院定点中医/专科医院定点社区卫生服务机构附录问题医保电子凭证4家定点医院的查询和修改北京医保个人账户资金定向使用北京医院排行榜单概述 …

基于BINN算法的CCPP全路径覆盖算法

1.CCPP整体算法文档 1.1 ccpp基础介绍 全路径覆盖算法&#xff08;CCPP: Complete Coverage Path Planning&#xff09;作为扫地机器人较为关键的组成部分&#xff0c;其问题的本质是&#xff1a;在栅格地图中,全覆盖路径规划问题就演变为寻找机器人的下一个移动位置,只有准确…

java计算机毕业设计ssm职工社保信息管理系统t22xh(附源码、数据库)

java计算机毕业设计ssm职工社保信息管理系统t22xh&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#…

建设银行互联网经营战略优化方案设计

目 录一、绪论 1 &#xff08;一&#xff09;项目背景 1 &#xff08;二&#xff09;项目意义 1 &#xff08;三&#xff09;项目内容和方法 1 二、互联网金融与我国商业银行概述 3 &#xff08;一&#xff09;互联网金融的内涵 3 &#xff08;二&#xff09;互联网金融的功…

【云计算与大数据计算】Hadoop MapReduce实战之统计每个单词出现次数、单词平均长度、Grep(附源码 )

需要全部代码请点赞关注收藏后评论区留言私信~~~ 下面通过WordCount&#xff0c;WordMean等几个例子讲解MapReduce的实际应用&#xff0c;编程环境都是以Hadoop MapReduce为基础 一、WordCount WordCount用于计算文件中每个单词出现的次数&#xff0c;非常适合采用MapReduce进…

描述统计 | 学习笔记 (全)

一.导论 统计学是通过收集&#xff0c;整理&#xff0c;分析&#xff0c;描述数据等手段&#xff0c;以达到推断所测对象的本质&#xff0c;甚至预测对象未来的一门综合性科学。其目的是探索数据的内在数量规律性&#xff0c;以达到对客观事物的科学认识 统计的本业是消化数据…

一种近红外I区荧光染料ICG-CBT 主要应用领域,是药品监督管理局(FDA)批准的体内应用染料

英文名称:ICG-CBT 保存条件:-20℃ 产品类别:化学试剂 结构式&#xff1a; 产品描述&#xff1a;&#xff08;ICG&#xff09;是一种近红外I区荧光染料[1]&#xff0c;是药品监督管理局&#xff08;FDA&#xff09;批准的体内应用染料。其激发和发射波长分别在785 nm、810 nm…

【C++初阶7-stringOJ】上手用一下

前言 本期通过几道OJ题&#xff0c;上手用用string。 1. 把字符串转换成整数 描述 将一个字符串转换成一个整数&#xff0c;要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0 数据范围&#xff1a;字符串长度满足0 ≤ n ≤100 进阶&am…

【读书笔记】万物原理——打开客观世界与主观情感的大门

被尹烨老师推荐种草的&#xff0c;以为是一本讲生命科学的科普书&#xff0c;看上了又以为是说量子物理等高端科学研究的&#xff0c;最后被互补性理论惊到了。这哪里只是一本打开认知客观世界的大门&#xff0c;还让我重识内心。那些看不见摸不着的情感&#xff0c;比如同情心…

数字孪生十大问题有哪些?通俗解释指的是什么?

数字孪生&#xff08;Digital Twins&#xff09;之火热&#xff0c;已经成为了一个不争的事实。数字孪生的概念&#xff0c;起源于制造业&#xff0c;现在已广泛应用到了智慧城市、智慧交通、智慧农业、智慧医疗、智能家居等行业。数字孪生十大问题有哪些&#xff1f;指的是什么…

018 | 服饰颜色与族群名称对颜色认知的影响 | 大学生创新训练项目申请书 | 极致技术工厂

研究目的 本项目以瑶、壮、汉三个民族、六个族群为研究对象&#xff0c;通过七个实验探索服饰颜色与族群名称对颜色认知的影响。重点提出以下两个问题&#xff1a; &#xff08;1&#xff09;服饰颜色是否影响少数民族个体的颜色偏好&#xff1f; &#xff08;2&#xff09;服…

刷完 300 道 LeetCode 题后,我膨胀到要飘起来了!纯正 Java 版

算法题就好像科举考试时代背的八股文&#xff0c;是知识改变命运的代表作。你不刷&#xff0c;不管是校招还是社招&#xff0c;就很过算法题这一关。 我整理的这份 LeetCode 刷题笔记足足 300 道&#xff0c;对算法薄弱和需要提高算法的同学很有帮助。 随便打开一道题解感受下…

【云原生】监视Docker桌面的容器内存和CPU使用情况

目录 一、如何监视Docker桌面的容器内存和CPU使用情况 1、stats命令 2、Docker 统计命令stats是如何工作的 2.1、命令与描述 2.2、OPTIONS 2.3、例子 2.4、格式化 3、满足资源使用扩展 4、如何安装“资源使用情况”扩展插件&#xff1f; 5、总结 一、如何监视Docker桌…

SQL记录

DateDiff函数 定义和用法 DATEDIFF() 函数返回两个日期之间的天数。 语法 DATEDIFF(date1,date2) date1 和 date2 参数是合法的日期或日期/时间表达式。 注释&#xff1a;只有值的日期部分参与计算。 实例 下面是 SELECT 语句&#xff1a; SELECT DATEDIFF(‘2008-11-30’,‘2…

WinRar去除弹窗广告的学习和研究

不可否认WinRar是一款优秀的解压缩软件&#xff0c;尤其是在Windows中使用还是较频繁的。 但是使用时弹出&#xff1a; 这就有点难受了。 那么怎么解决呢&#xff1f;好吧&#xff0c;以学习和研究为目的开始折腾...... 经过对WinRar不同版本的试用&#xff0c;原来这个弹窗是…

ubuntu修改网易云音乐分辨率显示

问题 网易云音乐不能随着系统显示的缩放比自动调整&#xff0c;分辨率较高的显示器上界面显示特别小。只能通过如下的办法解决&#xff1a; ubuntu修改网易云音乐分辨率显示&#xff0c;也就是修改显示 DPI 。 方法 sudo vim /usr/share/applications/netease-cloud-music.d…

12月12日

centos7查找java在哪&#xff0c;which java确认环境变量是否生效&#xff0c;可以输出一下&#xff1a;echo $JAVA_HOME同一个github账号上的所有的项目只需配置一次私钥和公钥&#xff0c;私钥和公钥的作用是你本机ip和这个账户所在github约定的一个对接方式&#xff0c;配置…