Iterator 迭代器

意图

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

动机

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

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

适用性

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

结构

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

参与者

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

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

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

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

效果

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

实现

  1 #include <iostream>
  2 using namespace std;
  3 
  4 typedef struct tagNode
  5 {
  6     int value;
  7     tagNode *pNext;
  8 }Node;
  9 
 10 class JTList
 11 {
 12 public:
 13     JTList() : m_pHead(NULL), m_pTail(NULL){};
 14     JTList(const JTList &);
 15     ~JTList();
 16     JTList &operator=(const JTList &);
 17 
 18     long GetCount() const;
 19     Node *Get(const long index) const;
 20     Node *First() const;
 21     Node *Last() const;
 22     bool Includes(const int &) const;
 23 
 24     void Append(const int &);
 25     void Remove(Node *pNode);
 26     void RemoveAll();
 27 
 28 private:
 29     Node *m_pHead;
 30     Node *m_pTail;
 31     long m_lCount;
 32 };
 33 
 34 class Iterator
 35 {
 36 public:
 37     virtual void First() = 0;
 38     virtual void Next() = 0;
 39     virtual bool IsDone() const = 0;
 40     virtual Node *CurrentItem() const = 0;
 41 };
 42 
 43 class JTListIterator : public Iterator
 44 {
 45 public:
 46     JTListIterator(JTList *pList) : m_pJTList(pList), m_pCurrent(NULL){}
 47 
 48     virtual void First();
 49     virtual void Next();
 50     virtual bool IsDone() const;
 51     virtual Node *CurrentItem() const;
 52 
 53 private:
 54     JTList *m_pJTList;
 55     Node *m_pCurrent;
 56 };
 57 
 58 JTList::~JTList()
 59 {
 60     Node *pCurrent = m_pHead;
 61     Node *pNextNode = NULL;
 62     while (pCurrent)
 63     {
 64         pNextNode = pCurrent->pNext;
 65         delete pCurrent;
 66         pCurrent = pNextNode;
 67     }
 68 }
 69 
 70 long JTList::GetCount()const
 71 {
 72     return m_lCount;
 73 }
 74 
 75 Node *JTList::Get(const long index) const
 76 {
 77     // The min index is 0, max index is count - 1
 78     if (index > m_lCount - 1 || index < 0)
 79     {
 80         return NULL;
 81     }
 82 
 83     int iPosTemp = 0;
 84     Node *pNodeTemp = m_pHead;
 85     while (pNodeTemp)
 86     {
 87         if (index == iPosTemp++)
 88         {
 89             return pNodeTemp;
 90         }
 91         pNodeTemp = pNodeTemp->pNext;
 92     }
 93     return NULL;
 94 }
 95 
 96 Node *JTList::First() const
 97 {
 98     return m_pHead;
 99 }
100 
101 Node *JTList::Last() const
102 {
103     return m_pTail;
104 }
105 
106 bool JTList::Includes(const int &value) const
107 {
108     Node *pNodeTemp = m_pHead;
109     while (pNodeTemp)
110     {
111         if (value == pNodeTemp->value)
112         {
113             return true;
114         }
115         pNodeTemp = pNodeTemp->pNext;
116     }
117     return false;
118 }
119 
120 void JTList::Append(const int &value)
121 {
122     // Create the new node
123     Node *pInsertNode = new Node;
124     pInsertNode->value = value;
125     pInsertNode->pNext = NULL;
126 
127     // This list is empty
128     if (m_pHead == NULL)
129     {
130         m_pHead = m_pTail = pInsertNode;
131     }
132     else
133     {
134         m_pTail->pNext = pInsertNode;
135         m_pTail = pInsertNode;
136     }
137     ++m_lCount;
138 }
139 
140 void JTList::Remove(Node *pNode)
141 {
142     if (pNode == NULL || m_pHead == NULL || m_pTail == NULL)
143     {
144         return;
145     }
146 
147     if (pNode == m_pHead) // If the deleting node is head node
148     {
149         Node *pNewHead = m_pHead->pNext;
150         m_pHead = pNewHead;
151     }
152     else
153     {
154         // To get the deleting node's previous node
155         Node *pPreviousNode = NULL;
156         Node *pCurrentNode = m_pHead;
157         while (pCurrentNode)
158         {
159             pPreviousNode = pCurrentNode;
160             pCurrentNode = pCurrentNode->pNext;
161             if (pCurrentNode == pNode)
162             {
163                 break;
164             }
165         }
166 
167         // To get the deleting node's next node
168         Node *pNextNode = pNode->pNext;
169 
170         // If pNextNode is NULL, it means the deleting node is the tail node, we should change the m_pTail pointer
171         if (pNextNode == NULL)
172         {
173             m_pTail = pPreviousNode;
174         }
175 
176         // Relink the list
177         pPreviousNode->pNext = pNextNode;
178     }
179 
180     // Delete the node
181     delete pNode;
182     pNode = NULL;
183     --m_lCount;
184 }
185 
186 void JTList::RemoveAll()
187 {
188     delete this;
189 }
190 
191 void JTListIterator::First()
192 {
193     m_pCurrent = m_pJTList->First();
194 }
195 
196 void JTListIterator::Next()
197 {
198     m_pCurrent = m_pCurrent->pNext;
199 }
200 
201 bool JTListIterator::IsDone() const
202 {
203     return m_pCurrent == m_pJTList->Last()->pNext;
204 }
205 
206 Node *JTListIterator::CurrentItem() const
207 {
208     return m_pCurrent;
209 }
210 
211 int main()
212 {
213     JTList *pJTList = new JTList;
214     pJTList->Append(10);
215     pJTList->Append(20);
216     pJTList->Append(30);
217     pJTList->Append(40);
218     pJTList->Append(50);
219     pJTList->Append(60);
220     pJTList->Append(70);
221     pJTList->Append(80);
222     pJTList->Append(90);
223     pJTList->Append(100);
224 
225     Iterator *pIterator = new JTListIterator(pJTList);
226 
227     // Print the list by JTListIterator
228     for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
229     {
230         cout << pIterator->CurrentItem()->value << "->";
231     }
232     cout << "NULL" << endl;
233 
234     // Test for removing
235     Node *pDeleteNode = NULL;
236     for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
237     {
238         pDeleteNode = pIterator->CurrentItem();
239         if (pDeleteNode->value == 100)
240         {
241             pJTList->Remove(pDeleteNode);
242             break;
243         }
244     }
245 
246     // Print the list by JTListIterator
247     for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
248     {
249         cout << pIterator->CurrentItem()->value << "->";
250     }
251     cout << "NULL" << endl;
252 
253     delete pIterator;
254     delete pJTList;
255 
256     return 0;
257 }

 

转载于:https://www.cnblogs.com/raichen/p/5675480.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值