C++ Iterator设计模式的思考 (Boolan学习笔记第13周)
2017-04-16 05:40
375 查看
Iterator设计模式是GOF里面的23中设计模式之一, 其定义是”提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。”
在没有学Iterator设计模式之前,如果要遍历容器里面的各个元素,我们可能想到的就是用一个链表把这些元素连起来,然后通过->next来遍历这些元素。但是这样就暴露了容器的内部细节。另外,如果有多个client同时遍历这个容器,可能还要给这个链表加个锁什么的,这样又浪费了系统资源。这些问题的原因都是容器的内部和它的遍历紧耦合了。
Iterator设计模式则把容器的内部实现和它的遍历实现了解耦,其结构图如下:
上面的各个部分说明如下:
Iterator:定义迭代器访问和遍历元素的接口;
ConcreteIterator:实现具体的迭代器;
Aggregate:定义的容器,创建相应迭代器对象的接口;
ConcreteAggregate:具体的容器实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
一个Iterator设计模式的基本代码如下:
在上面代码中,CollectionIterator就是结构图里面的ConcreteAggregate,里面包含了MyCollection的对象mc。在for loop中,里面的first(),isDone()和next()都是重载后的虚函数,实现运行时绑定。这样,用户并不知道MyCollection的内部细节,也可以实现遍历。
不过我想补充的是Iterator这种设计模式在JAVA里面用的很多,但是在C++里面已经过时了。为什么呢?因为Iterator设计模式是基于虚函数的,属于运行时绑定。我们知道虚函数运行时绑定就要查虚函数表,如果在一个很大的loop里面的话,这种虚函数绑定累计起来就耽误了很多时间,效率非常低。
而C++的STL是采用泛型编程,属于编译时绑定,效率非常高。那么为什么泛型编程可以在编译时绑定呢?因为它是基于Traits实现的,内部用到了类模板和偏特化。所以STL里面的Iterator并不是用的Iterator设计模式!
在没有学Iterator设计模式之前,如果要遍历容器里面的各个元素,我们可能想到的就是用一个链表把这些元素连起来,然后通过->next来遍历这些元素。但是这样就暴露了容器的内部细节。另外,如果有多个client同时遍历这个容器,可能还要给这个链表加个锁什么的,这样又浪费了系统资源。这些问题的原因都是容器的内部和它的遍历紧耦合了。
Iterator设计模式则把容器的内部实现和它的遍历实现了解耦,其结构图如下:
上面的各个部分说明如下:
Iterator:定义迭代器访问和遍历元素的接口;
ConcreteIterator:实现具体的迭代器;
Aggregate:定义的容器,创建相应迭代器对象的接口;
ConcreteAggregate:具体的容器实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
一个Iterator设计模式的基本代码如下:
template<typename T> class Iterator { public: virtual void first() = 0; virtual void next() = 0; virtual bool isDone() const = 0; virtual T& current() = 0; }; template<typename T> class MyCollection{ public: Iterator<T> GetIterator(){ //... } }; template<typename T> class CollectionIterator : public Iterator<T>{ MyCollection<T> mc; public: CollectionIterator(const MyCollection<T> & c): mc(c){ } void first() override { } void next() override { } bool isDone() const override{ } T& current() override{ } }; void MyAlgorithm() { MyCollection<int> mc; Iterator<int> iter= mc.GetIterator(); for (iter.first(); !iter.isDone(); iter.next()){ cout << iter.current() << endl; } }
在上面代码中,CollectionIterator就是结构图里面的ConcreteAggregate,里面包含了MyCollection的对象mc。在for loop中,里面的first(),isDone()和next()都是重载后的虚函数,实现运行时绑定。这样,用户并不知道MyCollection的内部细节,也可以实现遍历。
不过我想补充的是Iterator这种设计模式在JAVA里面用的很多,但是在C++里面已经过时了。为什么呢?因为Iterator设计模式是基于虚函数的,属于运行时绑定。我们知道虚函数运行时绑定就要查虚函数表,如果在一个很大的loop里面的话,这种虚函数绑定累计起来就耽误了很多时间,效率非常低。
而C++的STL是采用泛型编程,属于编译时绑定,效率非常高。那么为什么泛型编程可以在编译时绑定呢?因为它是基于Traits实现的,内部用到了类模板和偏特化。所以STL里面的Iterator并不是用的Iterator设计模式!
相关文章推荐
- c++设计模式(8)-Iterator模式
- C++设计模式之十六:Iterator 迭代器
- 设计模式(15) 迭代器模式(Iterator)C++实现
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 设计模式 原型模式与C++ & 设计模式的思考
- 设计模式C++之十四(Iterator迭代器模式)
- 我所理解的设计模式(C++实现)——迭代器模式(Iterator Pattern)
- 我所理解的设计模式(C++实现)——迭代器模式(Iterator Pattern)
- 设计模式C++描述----20.迭代器(Iterator)模式
- C++设计模式 之 “数据结构” 模式:Composite、Iterator、Chain of Resposibility
- c++设计模式:迭代器模式(Iterator Pattern)
- 测试类图Head First 设计模式 (九) 迭代器与组合模式(Iterator & Composite pattern) C++实现
- 设计模式的解析和实现(C++)之十八-Iterator模式
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 常见设计模式的解析和实现(C++)之十八-Iterator模式
- 常见设计模式的解析和实现(C++)之十八-Iterator模式
- c++设计模式:迭代器模式(Iterator Pattern)
- Head First 设计模式 (九) 迭代器与组合模式(Iterator & Composite pattern) C++实现
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- [C++设计模式] iterator 迭代器模式