设计模式之迭代器模式
迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而不暴露该对象的内部表示。该模式很好理解,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 }
测试结果如下图: