14.1.解释

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

main(),客户

IProject,产品接口

CProject,产品类

IIterator,迭代器接口

IProjectIterator,产品迭代器接口

CProjectIterator,产品迭代器实现类

说明:CProject实现产品类,能够返回一个迭代器的指针。这个迭代器将封装产品类里的一个数组。所以迭代器在运行Next函数时,可以遍历这个数组的所有元素。

简单来说,就是用代码实现vector<int>::iterator或vector<int>::const_iterator。

我们来看代码:

//IProject.h

#pragma once
#include "IProjectIterator.h"
#include <iostream>
using std::string;
class IProject
{
public:
    IProject(void)
    {
    }
    virtual ~IProject(void)
    {
    }
    virtual void Add(string name, int num, int cost) = 0;
    virtual string GetProjectInfo() = 0;
    virtual IProjectIterator* GetIterator() = 0;
    virtual void Erase() = 0;
};

//Project.h

#pragma once
#include "iproject.h"
#include "IProjectIterator.h"
#include <iostream>
#include <vector>
using std::string;
using std::vector;
class CProject :
    public IProject
{
public:
    CProject(void);
    CProject(string name, int num, int cost);
    ~CProject(void);
    string GetProjectInfo();
    void Add(string name, int num, int cost);
    IProjectIterator * GetIterator();
    void Erase();
private:
    string m_name;
    int m_num;
    int m_cost;
    vector<IProject*> m_projectList;
};

//Project.cpp

#include "StdAfx.h"
#include "Project.h"
#include "..\CommonDeclare\Convert.h"
#include "ProjectIterator.h"
#include <iostream>
#include <vector>
using std::string;
using std::vector;
CProject::CProject( void )
{
    m_name = "";
    m_num = 0;
    m_cost = 0;
}
CProject::CProject(string name, int num, int cost) :m_name(name), m_num(num), m_cost(cost)
{
}
CProject::~CProject(void)
{
}
string CProject::GetProjectInfo()
{
    string info = "";
    info.append("项目名称是:");
    info.append(this->m_name);
    info.append("\t项目人数:");
    info.append(CConvert::ToString(m_num));
    info.append("\t项目费用:");
    info.append(CConvert::ToString(m_cost));
    return info;
}
void CProject::Add( string name, int num, int cost )
{
    this->m_projectList.push_back(new CProject(name, num, cost));
}
IProjectIterator * CProject::GetIterator()
{
    return new CProjectIterator(this->m_projectList);
}
void CProject::Erase()
{
    vector<IProject*>::reverse_iterator projectDelIt = m_projectList.rbegin();
    for (; projectDelIt != m_projectList.rend(); projectDelIt++)
    {
        delete (*projectDelIt);
        (*projectDelIt) = NULL;
    }
    m_projectList.clear();
}

//IIterator.h

#pragma once
class IProject;
class IIterator
{
public:
    IIterator(void)
    {
    }
    virtual ~IIterator(void)
    {
    }
    virtual bool HasNext() = 0;
    virtual IProject * Next() = 0;
};

//IProjectIterator.h

#pragma once
#include "iiterator.h"
class IProject;
class IProjectIterator :
    public IIterator
{
public:
    IProjectIterator(void)
    {
    }
    virtual ~IProjectIterator(void)
    {
    }
    virtual bool HasNext() = 0;
    virtual IProject * Next() = 0;
};

//ProjectIterator.h

#pragma once
#include "iprojectiterator.h"
#include "IProject.h"
#include <vector>
using std::vector;
class CProjectIterator :
    public IProjectIterator
{
public:
    CProjectIterator(vector<IProject *> pl);
    ~CProjectIterator(void);
    bool HasNext();
    IProject * Next();
private:
    vector<IProject *> m_projectList;
    size_t m_currentItem;
};

//ProjectIterator.cpp

#include "StdAfx.h"
#include "ProjectIterator.h"
CProjectIterator::CProjectIterator(vector<IProject *> pl) : m_projectList(pl)
{
    m_currentItem = 0;
}
CProjectIterator::~CProjectIterator(void)
{
}
bool CProjectIterator::HasNext()
{
    bool b = true;
    if (m_currentItem >= m_projectList.size())
        b = false;
    return b;
}
IProject * CProjectIterator::Next()
{
    IProject *pp = m_projectList.at(m_currentItem ++);
    return pp;
}

// Iterator.cpp
#include "stdafx.h"
#include "IProject.h"
#include "Project.h"
#include "..\CommonDeclare\Convert.h"
#include "ProjectIterator.h"
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
void DoIt()
{
    cout << "----------未使用迭代模式----------" << endl;
    vector<IProject*> projectList;

projectList.push_back(new CProject("星球大战项目", 10, 100000));
    projectList.push_back(new CProject("扭转时空项目", 100, 10000000));
    projectList.push_back(new CProject("超人改造项目", 10000, 1000000000));

for (int i = 4; i < 6; i ++)
    {
        string name = "";
        name.append("第");
        name.append(CConvert::ToString(i));
        name.append("个项目");
        projectList.push_back(new CProject(name, i * 5, i * 1000000));
    }

vector<IProject*>::const_iterator projectIt = projectList.begin();
    for (; projectIt != projectList.end(); projectIt++)
        cout << (*projectIt)->GetProjectInfo().c_str() << endl;

vector<IProject*>::reverse_iterator projectDelIt = projectList.rbegin();
    for (; projectDelIt != projectList.rend(); projectDelIt++)
    {
        delete (*projectDelIt);
        (*projectDelIt) = NULL;
    }
    projectList.clear();
}
void DoNew()
{
    cout << "----------使用迭代模式----------" << endl;
    IProject *pproject = new CProject();
    pproject->Add("星球大战项目", 10, 100000);
    pproject->Add("扭转时空项目", 100, 10000000);
    pproject->Add("超人改造项目", 10000, 1000000000);

for (int i = 4; i < 6; i ++)
    {
        string name = "";
        name.append("第");
        name.append(CConvert::ToString(i));
        name.append("个项目");
        pproject->Add(name, i * 5, i * 1000000);
    }

IProjectIterator *pprojectIt = pproject->GetIterator();
    while(pprojectIt->HasNext())
    {
        IProject *p = dynamic_cast<IProject*>(pprojectIt->Next());
        cout << p->GetProjectInfo().c_str() << endl;
    }
    delete pprojectIt;
    pprojectIt = NULL;
    pproject->Erase();
    delete pproject;
    pproject = NULL;
}
int _tmain(int argc, _TCHAR* argv[])
{
    //使用Iterator模式之前
    DoIt();

//使用Iterator
    DoNew();

_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
    _CrtDumpMemoryLeaks();

return 0;
}

这个模式,可能有一点绕,需要再仔细的思考一番。本来希望把模式的工作方式,用最简单易懂的语言来总结,但其实这个总结更难。简单的模式还容易些理解,也容易总结,复杂的就难了。打算在之后,学习数据结构的过程中,都总结出这样一句话来。很期待后面对数据结构的学习,发现自己越来越爱学习了。

设计模式C++学习笔记之十四(Iterator迭代器模式)的更多相关文章

  1. 设计模式学习笔记(十六)迭代器模式及其在Java 容器中的应用

    迭代器(Iterator)模式,也叫做游标(Cursor)模式.我们知道,在Java 容器中,为了提高容器遍历的方便性,把遍历逻辑从不同类型的集合类中抽取出来,避免向外部暴露集合容器的内部结构. 一. ...

  2. 设计模式C++学习笔记之十(Builder建造者模式)

      建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.一段晦涩难懂的文字,实现创建不同表示的方法就是给创建的过程传入创建的参数.详细的还是看代码吧. 10.1.解释 ...

  3. VSTO学习笔记(十四)Excel数据透视表与PowerPivot

    原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...

  4. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  5. python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法

    python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...

  6. 如鹏网学习笔记(十四)ASP.NET

    Asp.net笔记 一.Socket类 进行网络编程的类,可以在两台计算机之间进行网络通讯 过程: 向服务器发送指令: GET /index.html HTTP/1.1 Host:127.0.0.1: ...

  7. 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据

    相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...

  8. Android学习笔记(十四)——自定义广播

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 我们除了可以通过广播接收器来接收系统广播, 还可以在应用程序中发送自定义的广播.下面我们来分别试一试发送自定义 ...

  9. Dynamic CRM 2013学习笔记(十四)复制/克隆记录

    经常有这样的需求,一个单据上有太多要填写的内容,有时还关联多个子单据,客户不想一个一个地填写,他们想从已有的单据上复制数据,克隆成一条新的记录.本文将介绍如何克隆一条记录,包括它的子单据以生成一条新的 ...

随机推荐

  1. Linux记录-linux系统监控命令汇总

    命令 功能应用 用法举例     free 查看内存使用情况,包括物理内存和虚拟内存 free -h或free -m     vmstat 对系统的整体情况进行统计,包括内核进程.虚拟内存.磁盘.陷阱 ...

  2. Structured Streaming + Kafka Integration Guide 结构化流+Kafka集成指南 (Kafka broker version 0.10.0 or higher)

    用于Kafka 0.10的结构化流集成从Kafka读取数据并将数据写入到Kafka. 1. Linking 对于使用SBT/Maven项目定义的Scala/Java应用程序,用以下工件artifact ...

  3. 5年GTD自我管理经验,一块听听

    我在胜利油田做了20多年的油田信息化工作,以前的我经常处于这样一种状态: 当我正在做着手边的一项事情时,头脑里却不断地蹦出来其它的事务,让我烦心不已,焦虑不安:PPT经常要拖到汇报当天的凌晨才做完,有 ...

  4. 谈谈java程序代码保护及license设计

    理论上讲,不存在牢不可破的漏洞,只是时间和成本问题.通常我们认为的不可破解,说的是破解需要难以接受的时间和成本.对于java程序来说,class文件很容易被反编译,所以理论上而言,对java程序做li ...

  5. 酷狗.kgtemp文件加密算法逆向

    该帖转载于孤心浪子--http://www.cnblogs.com/KMBlog/p/6877752.html 酷狗音乐上的一些歌曲是不能免费下载的,然而用户仍然可以离线试听,这说明有缓存文件,并且极 ...

  6. MySQL的一些基本命令笔记(2)

    1.逻辑运算符的补充 between 的用法:(在....之间) select column1,column2,......columnN from 表名 where columnX between ...

  7. tensorflow---文字识别

    读取数据的三种方法: 1. feeding : providing data when running each step : classifier.eval(feed_dict={input:my_ ...

  8. linux(Cnetos7)安装jdk和tomcatmysql,tomcat

    mysqllinux版本的地址 安装包下载 下载地址:http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.13-1.el6.x86_64.rp ...

  9. Debian Security Advisory(Debian安全报告) DSA-4404-1 chromium

    Package : chromium CVE ID : CVE-2019-5786 Clement Lecigne在chromium的文件读取器实现中发现了一个use-after-free(释放后重用 ...

  10. Codeforces 1065E(计数)

    题目链接 题意 限定字符串长度为$n$,字符集规模为$A$,以及$m$个数字$b$,对于任意数字$bi$满足长度为$bi$的前缀和后缀先反转再交换位置后形成的新串与原串视作相等,问存在多少不同串. 思 ...