一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

设计模式之迭代器模式

迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而不暴露该对象的内部表示。该模式很好理解,C++中的迭代器应该都用过,和那个差不多。其UML图如下:

 ConcreteIterator内部有一个聚合对象的引用(指针),而ConcreteAggregate依赖于ConcreteIterator。以前向链表为例,示例代码如下:

  1 // IteratorModel.h文件
  2 #pragma once
  3 #include <iostream>
  4 // 单向链表
  5 template<typename T>
  6 class node
  7 {
  8 public:
  9     node() : next(nullptr) { }
 10     T data;
 11     node * next;
 12 };
 13 // 迭代器
 14 template<typename T>
 15 class IteratorBase
 16 {
 17 public:
 18     virtual T first() = 0;
 19     virtual T next() = 0;
 20     virtual bool isDone() = 0;
 21     virtual T currentItem() = 0;
 22 };
 23 
 24 template<typename T>
 25 class Iterator;
 26 // 单项链表
 27 template<typename T>
 28 class forwardlist
 29 {
 30 public:
 31     forwardlist();
 32     ~forwardlist();
 33 private:
 34     unsigned int m_nLength;
 35     node<T> * m_HeadNode;
 36 public:
 37     friend class Iterator<T>;
 38     T getElement(unsigned int index);
 39     T getFirst();
 40     T getTail();
 41     unsigned int insertElement(unsigned int index, T elem);
 42     unsigned int appendElement(T elem);
 43     unsigned int insertFirst(T elem);
 44     unsigned int setValue(unsigned int index, T value);
 45     T deleteElement(unsigned int index);
 46     void deleteAll();
 47     unsigned int getLength();
 48     bool empty();
 49     Iterator<T> createIterator();
 50 private:
 51     node<T> * getFirstNode();
 52     node<T> * getNode(unsigned int index);
 53 };
 54 // 具体的迭代器
 55 template<typename T>
 56 class Iterator : public IteratorBase<T>
 57 {
 58 private:
 59     forwardlist<T> * m_list;
 60     node<T> * m_pCurrentNode;
 61     unsigned int m_nCurrentIndex;
 62 public:
 63     Iterator(forwardlist<T> * p):m_pCurrentNode(nullptr), m_nCurrentIndex(0u)
 64     {
 65         m_list = p;
 66         m_pCurrentNode = m_list->getFirstNode();
 67     }
 68     T first()
 69     {
 70         return m_list->getFirst();
 71     }
 72     T next()
 73     {
 74         if (isDone())
 75             return 0;
 76         if (nullptr == m_pCurrentNode)
 77             m_pCurrentNode = m_list->getNode(m_nCurrentIndex);
 78         node<T> * p = m_pCurrentNode->next;
 79         m_pCurrentNode = p;
 80         m_nCurrentIndex++;
 81         return p->data;
 82     }
 83     T currentItem()
 84     {
 85         return m_pCurrentNode->data;
 86     }
 87     bool isDone()
 88     {
 89         if (m_nCurrentIndex< m_list->getLength())
 90             return false;
 91         return true;
 92     }
 93     T operator*()
 94     {
 95         return currentItem();
 96     }
 97 };
 98 
 99 // forwardlist函数实现
100 // 创建迭代器函数
101 template<typename T>
102 Iterator<T> forwardlist<T>::createIterator()
103 {
104     return Iterator<T>(this);
105 }
106 
107 template<typename T>
108 forwardlist<T>::forwardlist() : m_nLength(0u), m_HeadNode(nullptr)
109 {
110     m_HeadNode = new node<T>;
111 }
112 
113 template<typename T>
114 forwardlist<T>::~forwardlist()
115 {
116     deleteAll();
117     delete m_HeadNode;
118 }
119 
120 template<typename T>
121 node<T> * forwardlist<T>::getNode(unsigned int index)
122 {
123     if (index >= m_nLength)
124     {
125         std::cout << "out of ranges" << std::endl;
126         return 0;
127     }
128     unsigned int n = 0;
129     node<T> * pnode = m_HeadNode;
130     while (n++ <= index)
131     {
132         pnode = pnode->next;
133     }
134     return pnode;
135 }
136 
137 template<typename T>
138 T forwardlist<T>::getElement(unsigned int index)
139 {
140     return getNode(index)->data;
141 }
142 
143 template<typename T>
144 T forwardlist<T>::getFirst()
145 {
146     return getElement(0u);
147 }
148 
149 template<typename T>
150 T forwardlist<T>::getTail()
151 {
152     if (m_nLength == 0u)
153     {
154         return T;
155     }
156     return getElement(m_nLength - 1);
157 }
158 
159 template<typename T>
160 unsigned int forwardlist<T>::insertElement(unsigned int index, T elem)
161 {
162     if (index > m_nLength)
163     {
164         std::cout << "out of ranges" << std::endl;
165         return 0;
166     }
167     node<T> * pnode = m_HeadNode;
168     unsigned int n = 0u;
169     while (n++ < index)// 定位到index上一个节点
170     {
171         pnode = pnode->next;
172     }
173     // 插入节点
174     node<T> *pnodeElem = new node<T>;
175     pnodeElem->data = elem;
176     pnodeElem->next = pnode->next;
177     pnode->next = pnodeElem;
178     // 长度增加
179     m_nLength++;
180     return index;
181 }
182 
183 template<typename T>
184 unsigned int forwardlist<T>::insertFirst(T elem)
185 {
186     return insertElement(0u, elem);
187 }
188 
189 template<typename T>
190 unsigned int forwardlist<T>::appendElement(T elem)
191 {
192     return insertElement(m_nLength, elem);
193 }
194 
195 template<typename T>
196 unsigned int setValue(unsigned int index, T value)
197 {
198     if (index >= m_nLength)
199     {
200         std::cout << "out of ranges" << std::endl;
201         return 0;
202     }
203     node<T> * pnode = m_HeadNode;
204     while (n++ <= index)// 定位到index
205     {
206         pnode = pnode->next;
207     }
208     pnode->data = value;
209     return index;
210 }
211 
212 template<typename T>
213 T forwardlist<T>::deleteElement(unsigned int index)
214 {
215     if (index >= m_nLength)
216     {
217         std::cout << "out of ranges" << std::endl;
218         return 0;
219     }
220     unsigned int n = 0u;
221     node<T> * pnode = m_HeadNode;
222     while (n++ < index)// 定位到index上一个节点
223     {
224         pnode = pnode->next;
225     }
226     // 删除节点
227     node<T> * pnodeTemp = pnode->next;
228     pnode->next = pnodeTemp->next;
229     T tTemp = pnodeTemp->data;
230     delete pnodeTemp;
231     pnodeTemp = nullptr;
232     // 长度减一
233     m_nLength--;
234     return tTemp;
235 }
236 
237 template<typename T>
238 void forwardlist<T>::deleteAll()
239 {
240     while (m_nLength > 0)
241     {
242         deleteElement(0);
243     }
244     m_HeadNode->next = nullptr;
245 }
246 
247 template<typename T>
248 unsigned int forwardlist<T>::getLength()
249 {
250     return m_nLength;
251 }
252 
253 template<typename T>
254 bool forwardlist<T>::empty()
255 {
256     return m_nLength > 0 ? false : true;
257 }
258 
259 template<typename T>
260 node<T> * forwardlist<T>::getFirstNode()
261 {
262     return getNode(0u);
263 }

测试代码如下:

 1 #include <iostream>
 2 #include "IteratorModel.h"
 3 
 4 int main()
 5 {
 6     using namespace std;
 7     // 迭代器模式
 8     forwardlist<char> list;
 9     list.insertElement(0u, 'A');
10     list.insertElement(1u, 'B');
11     list.insertElement(2u, 'C');
12     Iterator<char> it = list.createIterator();
13     std::cout << *it << endl;
14     std::cout << it.next() << endl;
15     std::cout << it.next() << endl;
16     cout << it.first() << endl;
17     cout << *it << endl;
18     if (!it.isDone())
19         cout << "结束" << endl;
20     else
21         cout << "未结束" << endl;
22 
23     getchar();
24     return 0;
25 }

测试结果如下图:

 

posted on 2023-07-07 13:54  一杯清酒邀明月  阅读(74)  评论(0编辑  收藏  举报