迭代器模式
1. 迭代器模式简介
把对容器中包含的内部对象的访问委让给外部类,使用 Iterator(遍历)按顺序进行遍历访问的设计模式。
如果不使用 Iterator 模式,会存在什么问题:
1.由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法
缺点: 容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。
2.让调用者自己实现遍历。直接暴露数据细节给外部。
缺点:往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。
2. 案例
迭代器能访问的本质:在迭代器中 持有 一个集合的 引用;所以通过迭代器,就可以访问集合。
1 #include <iostream>
2 using namespace std;
3 typedef int Object ;
4 #define SIZE 5
5
6 //注意类的顺序
7 class MyIterator //迭代器接口
8 {
9 public:
10 virtual void First() = 0;
11 virtual void Next() = 0;
12 virtual bool IsDone() = 0;
13 virtual Object CurrentItem() = 0;
14 };
15
16 class Aggregate //容器接口
17 {
18 public:
19 virtual Object getItem(int index) = 0;
20 virtual MyIterator *CreateIterator() = 0; //创建迭代器
21 virtual int getSize() = 0;
22 };
23
24 //具体的迭代器类
25 class ContreteIterator : public MyIterator
26 {
27 public:
28 ContreteIterator(Aggregate *ag)
29 {
30 _ag = ag;
31 _idx = 0;
32 }
33 ~ContreteIterator()
34 {
35 _ag = NULL;
36 _idx = 0;
37 }
38 virtual void First()
39 {
40 _idx = 0;
41 }
42 virtual void Next()
43 {
44 if (_idx < _ag->getSize())
45 {
46 _idx ++;
47 }
48 }
49 virtual bool IsDone()
50 {
51 return (_idx == _ag->getSize());
52 }
53 virtual Object CurrentItem()
54 {
55 return _ag->getItem(_idx);
56 }
57 protected:
58 private:
59 int _idx;
60 Aggregate *_ag; //在迭代器中 持有 一个集合的 引用;所以通过迭代器,就可以访问集合
61 };
62
63 //具体的容器类
64 class ConcreteAggregate : public Aggregate
65 {
66 public:
67 ConcreteAggregate()
68 {
69 for (int i=0; i<SIZE; i++)
70 {
71 object[i] = i+1;
72 }
73 }
74 virtual ~ConcreteAggregate()
75 {
76 }
77 virtual Object getItem(int index)
78 {
79 return object[index];
80 }
81 virtual MyIterator *CreateIterator()
82 {
83 return new ContreteIterator(this); //创建迭代器
84 }
85 virtual int getSize()
86 {
87 return SIZE;
88 }
89 protected:
90 private:
91 Object object[SIZE];
92 };
93
94 int main()
95 {
96 // 创建一个集合
97 Aggregate *ag = new ConcreteAggregate();
98 // 创建一个遍历这个集合的 迭代器
99 MyIterator *it = ag->CreateIterator();
100 //通过迭代器 遍历 集合
101 for (; !(it->IsDone()); it->Next() )
102 {
103 cout << it->CurrentItem() << " ";
104 }
105 //清理相关资源
106 delete it;
107 delete ag;
108 return 0;
109 }