Iterator,迭代器模式,C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
Iterator 几乎是大部分人在初学 C++的时候就无意之中接触到的第一种设计模式,因为在 STL 之中,所有的容器类都有与之相关的迭代器.以前初学 STL 的时候,时常在看到讲述迭代器作用的时候是这么说的:提供一种方式,使得算法和容器可以独立的变化,而且在访问容器对象的时候不必暴露容器的内部细节,具体是怎么做到这一点的呢?在 STL 的实现中,所有的迭代器(Iterator)都必须遵照一套规范,这套规范里面定义了几种类型的名称,比如对象的名称,指向对象的指针的名称,指向对象的引用的名称....等等,当新生成一个容器的时候与之对应的 Iterator 都要遵守这个规范里面所定义的名称,这样在外部看来虽然里面的实现细节不一样,但是作用(也就是对外的表象)都是一样的,通过某个名称可以得到容器包含的对象,通过某个名称可以得到容器包含的对象的指针等等的.而且,采用这个模式把访问容器的重任都交给了具体的 iterator 类中.于是,在使用 Iterator 来访问容器对象的算法不需要知道需要处理的是什么容器,只需要遵守事先约定好的 Iterator 的规范就可以了;而对于各个容器类而言,不管内部的事先如何,是树还是链表还是数组,只需要对外的接口也遵守 Iterator 的标准,这样算法(Iterator 的使用者)和容器(Iterator 的提供者)就能很好的进行合作,而且不必关心对方是如何事先的,简而言之,Iterator 就是算法和容器之间的一座桥梁.
在下面的实现中,抽象基类 Iterator 可以看做是前面提到的 Iterator 的规范,它提供了所有 Iterator 需要遵守的规范也就是对外的接口,而它的派生类 ConcreateIterator 则是 ConcreateAggregate 容器的迭代器,它遵照这个规范对容器进行迭代和访问操作。
|
|
#ifndef __ITERATOR_H__
#define __ITERATOR_H__
#include<iostream>
using namespace std;
typedef int Data;
class Iterator;
class Aggregate
{
public:
Aggregate();
virtual Iterator* createIterator() = 0;
virtual int size() = 0;
virtual Data& getItem(int idx) = 0;
virtual Iterator* begin() = 0;
virtual Iterator* end() = 0;
virtual ~Aggregate();
};
class ConcreteAggregate:public Aggregate
{
public:
ConcreteAggregate(int);
~ConcreteAggregate();
Iterator* createIterator();
int size();
Data& getItem(int idx);
Iterator* begin();
Iterator* end();
private:
int _size;
Data* _pData;
};
class Iterator
{
public:
virtual void first() = 0;
virtual void next() = 0;
virtual bool isDone() = 0;
virtual Data& currentItem() = 0;
virtual bool operator!=(Iterator&) = 0;
virtual Data& operator*() = 0;
virtual void operator++() = 0;
virtual int index() = 0;
virtual ~Iterator() ;
};
class ConcreteIterator:public Iterator
{
public:
ConcreteIterator(Aggregate*,int);
void first();
void next();
bool isDone();
Data& currentItem();
bool operator!=(Iterator&);
Data& operator*();
void operator++();
int index();
~ConcreteIterator();
private:
Aggregate* _pAggregate;
int _idx;
};
#endif
|
#include<iostream>
#include"iterator.h"
using namespace std;
Aggregate::Aggregate()
{
cout<<"Aggregate()"<<endl;
}
Aggregate::~Aggregate()
{
cout<<"~Aggregate()"<<endl;
}
ConcreteAggregate::ConcreteAggregate(int size):_size(size)
{
cout<<"ConcreteAggregate()"<<endl;
_pData = new Data[_size];
for(int i=0;i<_size;++i)
_pData[i] = i+1;
}
ConcreteAggregate::~ConcreteAggregate()
{
cout<<"~ConcreteAggregate()"<<endl;
delete _pData;
}
Iterator* ConcreteAggregate::createIterator()
{
return new ConcreteIterator(this,0); // 生成组合类对象
}
int ConcreteAggregate::size()
{
return _size;
}
Data& ConcreteAggregate::getItem(int idx)
{
return _pData[idx];
}
Iterator* ConcreteAggregate::begin()
{
return new ConcreteIterator(this,0); // 生成组合类对象
}
Iterator* ConcreteAggregate::end()
{
return new ConcreteIterator(this,_size); // 返回一个指向_pData末尾的Iterator对象
}
/* ************************************* */
Iterator::~Iterator()
{
cout<<"~Iterator()"<<endl;
}
ConcreteIterator::ConcreteIterator(Aggregate* pa,int idx):_pAggregate(pa),_idx(idx)
{
cout<<"ConcreteIterator(Aggregate*,int)"<<endl;
}
ConcreteIterator::~ConcreteIterator()
{
cout<<"~ConcreteIterator()"<<endl;
}
void ConcreteIterator::first()
{
_idx = 0; // 取Iterator类造出的对象的第一个元素
}
void ConcreteIterator::next()
{
++_idx;
}
bool ConcreteIterator::isDone()
{
return _idx == _pAggregate->size();
}
Data& ConcreteIterator::currentItem()
{
return _pAggregate->getItem(_idx);
}
int ConcreteIterator::index()
{
return _idx; // 获取Iterator类对象的大小
}
bool ConcreteIterator::operator!=(Iterator& rhs)
{
return _idx != rhs.index();
}
Data& ConcreteIterator::operator*()
{
return currentItem();
}
void ConcreteIterator::operator++()
{
++_idx;
}
|
// 提供一种方法顺序访问一个聚合对象中各个元素,,而又不需暴露该对象的内部表示.
#include<iostream>
#include"iterator.h"
using namespace std;
int main()
{
Aggregate* pAggregate = new ConcreteAggregate(5);
Iterator* pIterator = pAggregate->createIterator();
for(;false==pIterator->isDone();pIterator->next())
{
cout<<pIterator->currentItem()<<" ";
}
cout<<endl<<endl;
Iterator* it1 = pAggregate->begin(); // 建一个产品类指针,指向工厂类造的一个对象
// 内部实现就是it1指向上面创建的数组的开头ConcreteIterator(this,0);
Iterator* it2 = pAggregate->end();
for(;(*it1)!=(*it2);++(*it1);)
{
cout<<*(*it1)<<endl;
}
delete pAggregate;
delete pIterator;
return 0;
}
|
Iterator,迭代器模式,C++描述的更多相关文章
- [设计模式] Iterator - 迭代器模式:由一份奥利奥早餐联想到的设计模式
Iterator - 迭代器模式 目录 前言 回顾 UML 类图 代码分析 抽象的 UML 类图 思考 前言 这是一包奥利奥(数组),里面藏了很多块奥利奥饼干(数组中的元素),我将它们放在一个碟子上慢 ...
- [C# 设计模式] Iterator - 迭代器模式:我与一份奥利奥早餐的故事
Iterator - 迭代器模式 目录 前言 回顾 UML 类图 代码分析 抽象的 UML 类图 思考 前言 这是一包奥利奥(数组),里面藏了很多块奥利奥饼干(数组中的元素),我将它们放在一个碟子上慢 ...
- 设计模式17:Iterator 迭代器模式(行为型模式)
Iterator 迭代器模式(行为型模式) 动机(Motivation) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码可以透 ...
- 设计模式(十五):Iterator迭代器模式 -- 行为型模式
1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的有用方法,但通常你会处理一组对象或者集合. 集合不一定是均一的.图形用 ...
- 设计模式(16)--Iterator(迭代器模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 迭代模式又叫游标(Cursor)模式,是对象的行为模式.迭代模式可以顺序地访问一个聚集中的元素而不 ...
- Iterator 迭代器模式 MD
迭代器模式 简介 Iterator模式是行为模式之一,它把对容器中包含的内部对象的访问[委让]给外部类,使用Iterator按顺序进行遍历访问. 在程序设计中,经常有这种情况:需要从大量的数据集合中一 ...
- Iterator - 迭代器模式
定义 提供一个方法顺序訪问一个聚合对象中个各个元素,而又不须要暴露该对象的内部结构. 案例 一个聚合对象.如一个列表List.应该提供一种方法来让别人能够訪问它的元素.而又不用暴露内部结构.迭代器模式 ...
- [C++设计模式] iterator 迭代器模式
迭代器模式定义:提供一种方法顺序訪问一个聚合对象中各个元素,而又不须要暴露该对象. 迭代器分内部迭代器和外部迭代器.内部迭代器与对象耦合紧密,不推荐使用. 外部迭代器与聚合容器的内部对象松耦合,推荐使 ...
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
14.1.解释 概念:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. main(),客户 IProject,产品接口 CProject,产品类 IIterator,迭代 ...
- Iterator(迭代器模式)--(超市管理者)
这个Iterator就是收银台干的活. package patterns.actions.iterator; public interface IteratorList { boolean isEmp ...
随机推荐
- Python PyQt5 Pycharm 环境搭建及配置
PyQt5相关安装 python 版本 python 3.6.3 1.安装PyQt5 执行命令: pip install pyqt5 2.安装PyQt5-tools 执行命令:pip install ...
- Jenkins与Gitlab集成
一.安装jenkinshttps://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/ #清华yum源 yum -y install java-1.8. ...
- Confluence 6 可以自定义的元素
色彩配色方案允许你对 UI 中的元素色彩进行编辑,包括顶部条,标签页和背景色. 有一些下面的 UI 元素被用在特定的主题中,配色方案的修改可能不会对这些元素有效. 顶部条(Top Bar)—— 顶部导 ...
- python模块--pickle&json&shelve
使用file文件处理时,写入的必须是str ,否则会报错. 例如:要把一个字典写入文件,写入时会报错 ,就算转换成str格式写入,读取的时候也不能按照dict格式读. >>> inf ...
- Problem F. Grab The Tree HDU - 6324
题意:给出一棵n个节点的树,每个节点有一个权值,Q和T玩游戏,Q先选一些不相邻的节点,T选剩下的节点,每个人的分数是所选节点的权值的异或和,权值大的胜出,问胜出的是谁. 题解: 话说,这题后面的边跟解 ...
- CentOS6.8下实现配置配额
CentOS6.8下实现配置配额 Linux系统是支持多用户的,即允许多个用户同时使用linux系统,普通用户在/home/目录下均有自己的家目录,在默认状态下,各个用户可以在自己的家目录下任意创建文 ...
- 20165309 实验二 Java面向对象程序设计
2017-2018-2 20165309实验二<Java面向对象程序设计>实验报告 一.实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初 ...
- 在c++运行后出现PDB或者什么巴拉巴拉已经加载符号了的话
“stl常用排序算法.exe”(Win32): 已加载“E:\vs2015\project\stl常用排序算法\Debug\stl常用排序算法.exe”.已加载符号. “stl常用排序算法.exe”( ...
- (二)使用数组长度实现ADT bag(java)
目录 1.使用固定大小的数组实现ADT bag 包 1.1 一组核心方法 1.2 实现核心方法 1.3 让实现安全 1.4 测试核心方法 1.5 实现更多的方法 1.6 删除项的方法 1.7 测试 ...
- 本地仓库有jar包maven依然报错的原因
本地Maven仓库有所需jar包依然报错,missing……………… 既然有这个jar包为什么还会报错呢? 找到本地仓库后发现里面有一个_remote.repositories文件 问题在_remot ...