设计模式C++学习笔记之十四(Iterator迭代器模式)
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迭代器模式)的更多相关文章
- 设计模式学习笔记(十六)迭代器模式及其在Java 容器中的应用
迭代器(Iterator)模式,也叫做游标(Cursor)模式.我们知道,在Java 容器中,为了提高容器遍历的方便性,把遍历逻辑从不同类型的集合类中抽取出来,避免向外部暴露集合容器的内部结构. 一. ...
- 设计模式C++学习笔记之十(Builder建造者模式)
建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.一段晦涩难懂的文字,实现创建不同表示的方法就是给创建的过程传入创建的参数.详细的还是看代码吧. 10.1.解释 ...
- VSTO学习笔记(十四)Excel数据透视表与PowerPivot
原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...
- Python学习笔记(十四)
Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- 如鹏网学习笔记(十四)ASP.NET
Asp.net笔记 一.Socket类 进行网络编程的类,可以在两台计算机之间进行网络通讯 过程: 向服务器发送指令: GET /index.html HTTP/1.1 Host:127.0.0.1: ...
- 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据
相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...
- Android学习笔记(十四)——自定义广播
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 我们除了可以通过广播接收器来接收系统广播, 还可以在应用程序中发送自定义的广播.下面我们来分别试一试发送自定义 ...
- Dynamic CRM 2013学习笔记(十四)复制/克隆记录
经常有这样的需求,一个单据上有太多要填写的内容,有时还关联多个子单据,客户不想一个一个地填写,他们想从已有的单据上复制数据,克隆成一条新的记录.本文将介绍如何克隆一条记录,包括它的子单据以生成一条新的 ...
随机推荐
- 【JQ】jq动态绑定事件.on()、解绑事件off()
#JQ 绑定与解绑事件的方法的历史演变 1. jquery1.4 及之前的版本,由.click() 或 .bind()方法绑定的事件,不能适用脚本创建的新元素:即是说页面加载完成后,再动态创建的DOM ...
- jquery validate 详解二
原文:http://blog.sina.com.cn/s/blog_608475eb0100h3h2.html 这里只是第二篇,前面的内容请参阅上一篇 五.常用方法及注意问题 1.用其他方式替代默认的 ...
- Docker记录-Docker部署记录
1.Docker介绍 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后 ...
- C#设计模式(0)——设计原则
设计原则 使用设计模式的根本原因是适应变化,提高代码复用率,使软件更具有可维护性和可扩展性.在进行设计的时候,我们需要遵循以下几个原则:单一职责原则.开闭原则.里氏替代原则.依赖倒置原则.接口隔离原则 ...
- 端口与进程-----Window cmd命令
******************** windows 篇 ********************** cmd命令: services.msc 打开本地服务页面 一.查看windows系统 ...
- 【leetcode-69】 x 的平方根
(主要是越界问题) 实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 ...
- overlay网络隔离实验失败记录
按照 https://www.cnblogs.com/CloudMan6/p/7341487.html进行操作,实验结果与老师文章中的正好相反,不同 overlay 网络中的主机可以通信,验证部分见下 ...
- jquery添加
添加新内容的四个 jQuery 方法: append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() ...
- Ubuntu18.04终端设置为zsh后的问题记录
1. 在将终端从bash切换成zsh后,需要将 .bashrc 下的一些配置迁移到 .zshrc 中: 例如,笔者在使用zsh中使用virtualenv及virtualenvwrapper的相关命令时 ...
- 剑指Offer-滑动窗口的最大值
题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6 ...