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. UEFI BIOS Rootkit Analysis

    catalog . BIOS简介 . UEFI BIOS . EFI编程简介 . UEFI Rootkit 1. BIOS简介 BIOS("Basic Input Output System ...

  2. Journal Storage Directory not formatted

    类型一: 当你从异常信息中看到JournalNode not formatted,如果在异常中看到三个节点都提示需要格式化JournalNode. 如果你是新建集群,你可以重新格式化NameNode, ...

  3. Spring 在 xml配置文件 或 annotation 注解中 运用Spring EL表达式

    Spring  EL 一:在Spring xml 配置文件中运用   Spring EL Spring EL 采用 #{Sp Expression  Language} 即 #{spring表达式} ...

  4. 10.外观模式(Facade Pattern)

    动机(Motivate):    在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化.那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的 ...

  5. Sublime Text3 里使用MarkDown如何预览

    安装需要的包: 1.markdown editing 2.markdown preview 具体的步骤是: 1.按住ctrl + shift + p 来调出一个弹出的输入框 :2.输入package  ...

  6. 关于Mui严格模式下的报错解决方案

    前言:作为一名程序员遇到Bug总是在所难免的,但是记住"不二过",今天在Vue开发中遇到了一个报错让我纠结了许久,找了许久, 报错的原因是使用了mui导入其js文件导致的. 报错信 ...

  7. Golang入门教程(六)关键字和数据类型

    在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. 一.25个关键字 二.18 ...

  8. STL优先队列

    #include<cstdio> #include<iostream> #include<algorithm> #include<queue> usin ...

  9. 044、vloume声明周期管理(2019-03-07 周四)

    参考https://www.cnblogs.com/CloudMan6/p/7214828.html   如果Data Volume 中存放的是重要的应用数据,如何管理volume对应用至关重要.   ...

  10. jspdf简单使用

    安装 npm install jspdf --save 英文输出 import jsPDF from 'jspdf-customfonts' let doc = new jsPDF() doc.tex ...