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. Java Hibernate中的悲观锁和乐观锁的实现

    锁(locking) 业务逻辑的实现过程中,往往需要保证数据访问的排他性.如在金融系统的日终结算 处理中,我们希望针对某个cut-off时间点的数据进行处理,而不希望在结算进行过程中 (可能是几秒种, ...

  2. Java插件之Jrebel

    Jrebel是干嘛的?当你在Java Web的项目中修改一些代码的时候(成员代码),想要生效必须重启服务器.但是每次修改代码都得重启服务器?重启着时间很长的,太麻烦了. Jrebel隆重出场,它可以使 ...

  3. JAVA核心技术I---JAVA基础知识(回顾)

    一:对象实例化问题: public class Rectangle { ; ; public int area() { return width * height; } } 则如下代码输出结果为: R ...

  4. Kafka技术内幕 读书笔记之(六) 存储层——日志的读写

    -Kafka是一个分布式的( distributed ).分区的( partitioned ).复制的( replicated )提交日志( commitlog )服务 . “分布式”是所有分布式系统 ...

  5. Linux记录-文件格式

    yum -y install dos2unix dos2unix filename

  6. layui(二)——layer组件常见用法总结

    layer是layui的代表作,功能十分强大,为方便以后快速配置这里对其常见用法做了简单总结 一.常用调用方式 //1.普通消息:alert(content,[options],[yesCallBac ...

  7. Chrome DevTools: Export your raw Code Coverage Data

    The Code Coverage tool visually shows you which lines of code in your CSS and JavaScript are used an ...

  8. Entity Framework Code First 学习日记(1)精

    我最近几天正在学习Entity Framework Code First.我打算分享一系列的学习笔记,今天是第一部分: 为什么要使用Code First: 近 年来,随着domain driven d ...

  9. 细说java之编码

    JAVA编程中涉及的编码 1.J2EE中涉及的编码(1) HttpServletResponse响应内容编码: resp.setCharacterEncoding(charset); (2)JSP文件 ...

  10. Android上禁止屏幕旋转

    看网上讲了很多,设置很多属性,设置了很多,其实最关键的一点是这个 @Overrideprotected void onResume() { /** * 设置为横屏 */ if(getRequested ...