意图

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

动机

一个聚合对象, 如列表(list), 应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构

迭代器类定义了一个访问该列表元素的接口。迭代器对象负责跟踪当前的元素 ;即, 它知道哪些元素已经遍历过了。

适用性

  • 访问一个聚合对象的内容而无需暴露它的内部表示。
  • 支持对聚合对象的多种遍历。
  • 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)。

结构

定义一个抽象列表类AbstractList,它提供操作列表的公共接口。类似地,我们也需要一个抽象的迭代器类Iterator,它定义公共的迭代接口。然后我们可以为每个不同的列表实现定义具体的Iterator子类。这样迭代机制就与具体的聚合类无关了。

参与者

Iterator:迭代器定义访问和遍历元素的接口。

ConcreteIterator:具体迭代器实现迭代器接口;对该聚合遍历时跟踪当前位置。

Aggregate:聚合定义创建相应迭代器对象的接口。

ConcreteAggregate:具体聚合实现创建相应迭代器的接口,该操作返回ConcreteAggregate的一个适当的实例。

效果

  • 访问一个聚合对象的内容而无需暴露它的内部表示;
  • 支持对聚合对象的多种遍历(从前到后,从后到前);
  • 为遍历不同的聚合结构提供一个统一的接口,即支持多态迭代。

实现

 #include <iostream>
using namespace std; typedef struct tagNode
{
int value;
tagNode *pNext;
}Node; class JTList
{
public:
JTList() : m_pHead(NULL), m_pTail(NULL){};
JTList(const JTList &);
~JTList();
JTList &operator=(const JTList &); long GetCount() const;
Node *Get(const long index) const;
Node *First() const;
Node *Last() const;
bool Includes(const int &) const; void Append(const int &);
void Remove(Node *pNode);
void RemoveAll(); private:
Node *m_pHead;
Node *m_pTail;
long m_lCount;
}; class Iterator
{
public:
virtual void First() = ;
virtual void Next() = ;
virtual bool IsDone() const = ;
virtual Node *CurrentItem() const = ;
}; class JTListIterator : public Iterator
{
public:
JTListIterator(JTList *pList) : m_pJTList(pList), m_pCurrent(NULL){} virtual void First();
virtual void Next();
virtual bool IsDone() const;
virtual Node *CurrentItem() const; private:
JTList *m_pJTList;
Node *m_pCurrent;
}; JTList::~JTList()
{
Node *pCurrent = m_pHead;
Node *pNextNode = NULL;
while (pCurrent)
{
pNextNode = pCurrent->pNext;
delete pCurrent;
pCurrent = pNextNode;
}
} long JTList::GetCount()const
{
return m_lCount;
} Node *JTList::Get(const long index) const
{
// The min index is 0, max index is count - 1
if (index > m_lCount - || index < )
{
return NULL;
} int iPosTemp = ;
Node *pNodeTemp = m_pHead;
while (pNodeTemp)
{
if (index == iPosTemp++)
{
return pNodeTemp;
}
pNodeTemp = pNodeTemp->pNext;
}
return NULL;
} Node *JTList::First() const
{
return m_pHead;
} Node *JTList::Last() const
{
return m_pTail;
} bool JTList::Includes(const int &value) const
{
Node *pNodeTemp = m_pHead;
while (pNodeTemp)
{
if (value == pNodeTemp->value)
{
return true;
}
pNodeTemp = pNodeTemp->pNext;
}
return false;
} void JTList::Append(const int &value)
{
// Create the new node
Node *pInsertNode = new Node;
pInsertNode->value = value;
pInsertNode->pNext = NULL; // This list is empty
if (m_pHead == NULL)
{
m_pHead = m_pTail = pInsertNode;
}
else
{
m_pTail->pNext = pInsertNode;
m_pTail = pInsertNode;
}
++m_lCount;
} void JTList::Remove(Node *pNode)
{
if (pNode == NULL || m_pHead == NULL || m_pTail == NULL)
{
return;
} if (pNode == m_pHead) // If the deleting node is head node
{
Node *pNewHead = m_pHead->pNext;
m_pHead = pNewHead;
}
else
{
// To get the deleting node's previous node
Node *pPreviousNode = NULL;
Node *pCurrentNode = m_pHead;
while (pCurrentNode)
{
pPreviousNode = pCurrentNode;
pCurrentNode = pCurrentNode->pNext;
if (pCurrentNode == pNode)
{
break;
}
} // To get the deleting node's next node
Node *pNextNode = pNode->pNext; // If pNextNode is NULL, it means the deleting node is the tail node, we should change the m_pTail pointer
if (pNextNode == NULL)
{
m_pTail = pPreviousNode;
} // Relink the list
pPreviousNode->pNext = pNextNode;
} // Delete the node
delete pNode;
pNode = NULL;
--m_lCount;
} void JTList::RemoveAll()
{
delete this;
} void JTListIterator::First()
{
m_pCurrent = m_pJTList->First();
} void JTListIterator::Next()
{
m_pCurrent = m_pCurrent->pNext;
} bool JTListIterator::IsDone() const
{
return m_pCurrent == m_pJTList->Last()->pNext;
} Node *JTListIterator::CurrentItem() const
{
return m_pCurrent;
} int main()
{
JTList *pJTList = new JTList;
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append(); Iterator *pIterator = new JTListIterator(pJTList); // Print the list by JTListIterator
for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
{
cout << pIterator->CurrentItem()->value << "->";
}
cout << "NULL" << endl; // Test for removing
Node *pDeleteNode = NULL;
for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
{
pDeleteNode = pIterator->CurrentItem();
if (pDeleteNode->value == )
{
pJTList->Remove(pDeleteNode);
break;
}
} // Print the list by JTListIterator
for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
{
cout << pIterator->CurrentItem()->value << "->";
}
cout << "NULL" << endl; delete pIterator;
delete pJTList; return ;
}

Iterator 迭代器的更多相关文章

  1. ES6笔记(6)-- Set、Map结构和Iterator迭代器

    系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...

  2. vector容器+iterator迭代器

    关于vector容器的详细描述,可参考:http://www.jb51.net/article/41648.htm   关于iterator迭代器的描述,可参考http://www.cppblog.c ...

  3. C++ Iterator迭代器介绍及Iterator迭代器用法代码举例

    C++ Iterator迭代器介绍 迭代器可被用来访问一个容器类的所包函的全部元素,其行为像一个指针.举一个例子,你可用一个迭代器来实现对vector容器中所含元素的遍历.有这么几种迭代器如下: 迭代 ...

  4. 【转】Java学习之Iterator(迭代器)的一般用法 (转)

    [转]Java学习之Iterator(迭代器)的一般用法 (转) 迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭 ...

  5. 设计模式(十五):Iterator迭代器模式 -- 行为型模式

    1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的有用方法,但通常你会处理一组对象或者集合. 集合不一定是均一的.图形用 ...

  6. C#:iterator 迭代器/partial class 分布类/泛型

    C#:iterator 迭代器/partial class 分布类/泛型 iterator 迭代器 写个最简单的迭代,(迭代一个字符串数组): 1.实现接口中的方法: 1 using System; ...

  7. [设计模式] Iterator - 迭代器模式:由一份奥利奥早餐联想到的设计模式

    Iterator - 迭代器模式 目录 前言 回顾 UML 类图 代码分析 抽象的 UML 类图 思考 前言 这是一包奥利奥(数组),里面藏了很多块奥利奥饼干(数组中的元素),我将它们放在一个碟子上慢 ...

  8. Python 中 Iterator(迭代器)和Iterable(迭代对象)的区别

    直接可以用作for循环的数据类型有以下几种: tuple.list.dict.str等, 上述数据类型可以用作for循环的叫做可迭代对象Iterable.可以使用isinstance判断一个对象是否是 ...

  9. 使用Iterator迭代器循环集合

    1.Iterator迭代器用于遍历集合元素,获取迭代器可以使用. 2.Iterator提供了统一遍历集合元素的 方式 ,其提供了用于遍历集合的连个方法----- boolean  hasNext()判 ...

  10. [C# 设计模式] Iterator - 迭代器模式:我与一份奥利奥早餐的故事

    Iterator - 迭代器模式 目录 前言 回顾 UML 类图 代码分析 抽象的 UML 类图 思考 前言 这是一包奥利奥(数组),里面藏了很多块奥利奥饼干(数组中的元素),我将它们放在一个碟子上慢 ...

随机推荐

  1. Java基础-DButils工具类(QueryRunner)详解

    Java基础-DButils工具类(QueryRunner)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC ...

  2. CSS3 box-sizing:border-box的好处

    无论如何改动border,margin与padding的值,都不会导致box总尺寸发生变化.

  3. Shell记录-Shell脚本基础(一)

    Shell 注释: 你可以把注释,在你的脚本如下: #!/bin/bash # Author : Zara Ali # Copyright (c) Tutorialsyiibai.com # Scri ...

  4. jquery bxslider幻灯片样式改造

    找了很多jquery的幻灯片,都觉得不是很好,最后发现bxslider兼容性最好,移动设备支持手动翻动. 但是官方提供的显示效果真的很难看,让人难以接受.最后只能自己DIY了. bxslider官方样 ...

  5. PartyPlay发布版

    发布版本在beta版本的基础之上修改了pose王中的显示函数部分,使其可以正常的多次显示不同图片,不会出现卡在一张图片的问题上. 因此总的发布版本内容: 1.谁是卧底: 点击进入谁是卧底,进入游戏前的 ...

  6. 20155231 2016-2017-2 《Java程序设计》第7周学习总结

    20155231 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 学习目标 了解Lambda语法 了解方法引用 了解Fucntional与Stream API ...

  7. [洛谷P1228]地毯填补问题 题解(分治)

    Description 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将除公主站立的地方外的 ...

  8. HDU 2063 过山车 二分匹配

    解题报告:有m个女生和n个男生要结成伴坐过山车,每个女生都有几个自己想选择的男生,然后要你确定最多能组成多少对组合. 最裸的一个二分匹配,这是我第一次写二分匹配,给我最大的感受就是看那些人讲的匈牙利算 ...

  9. 【译】第十一篇 SQL Server代理维护计划

    本篇文章是SQL Server代理系列的第十一篇,详细内容请参考原文 在这一系列的上一篇,我们看了使用代理帐户模仿Windows安全上下文完成作业步骤的工作.大多数子系统支持代理账户,同时子系统限制代 ...

  10. 2015.07.15——prime素数

    prime素数 1.素数也叫质数,定义是一个数只能被1和它自身整除. 素数从2开始,0,1都不是素数. 2.素数的判断(C++) 3.给定某个数,求小于这个数的所有素数 2.素数的判断(C++) bo ...