C++二十三种设计模式之迭代器模式
- 一、组成
- 二、特点
- 三、目的
- 四、缺点
- 五、示例代码
一、组成
抽象聚合类:存储集合元素,声明管理集合元素接口。
具体聚合类:实现管理集合元素接口。
抽象迭代器类:声明访问和遍历聚合类元素的接口。
具体迭代器类:实现访问和遍历聚合类元素的接口。
二、特点
1、有两种定义模板的方式,template和template。建议使用template,与类定义区分明显。
2、具体聚合类使用抽象聚合类的智能指针成员变量时,需要通过this指针来调用,否则可能会出现找不到该变量的编译报错。
三、目的
不暴露集合底层实现细节的情况下访问和遍历集合中所有元素。
四、缺点
1、性能消耗问题,使用迭代器需要额外的间接层来访问元素,比直接访问元素慢。
2、类膨胀,为了支持多种遍历方式,需要定义多种具体迭代器类。
五、示例代码
#include<iostream>
#include <vector>
#include <list>
#include <string>
#include <mutex>
#include <map>
#include<stack>using namespace std;template<typename T>
class Node;//节点类template<typename T>
class AbstractLinkedList;//抽象聚合类template<typename T>
class LinkedList;//具体聚合类template<typename T>
class AbstractIterator;//抽象迭代器类template<typename T>
class Iterator;//具体迭代器类template<typename T>
class Node {
public:Node(T data) : m_data(data), next(nullptr) {}~Node() {cout << "~Node" << endl;}T m_data;shared_ptr<Node<T>> next;
};template<typename T>
class AbstractIterator {
protected:AbstractIterator() {}virtual void Next() = 0;virtual bool hasNext() const = 0;
public:shared_ptr<Node<T>> m_current;
};template<typename T>
class Iterator :public AbstractIterator<T> {//具体迭代器类
public:Iterator() {}Iterator(shared_ptr<Node<T>> cur) {this->m_current = cur;}void Next() {this->m_current = (this->m_current)->next;};bool hasNext() const {return ((this->m_current) != nullptr);};
};template<typename T>
class AbstractLinkedList {
protected:virtual Iterator<T> Begin() = 0;virtual void append(T value) = 0;shared_ptr<Node<T>> m_head;
};template<typename T>
class LinkedList :public AbstractLinkedList<T> {
public:Iterator<T> Begin() {return Iterator<T>(this->m_head);}void append(T value) {auto newNode = make_shared<Node<T>>(value);if (!this->m_head) {this->m_head = newNode;}else {auto cur = this->m_head;while (cur->next) {cur = cur->next;}cur->next = newNode;}}
};int main() {unique_ptr<LinkedList<int>> linkedList = make_unique<LinkedList<int>>();linkedList->append(1);linkedList->append(2);linkedList->append(3);for (Iterator<int> iter = linkedList->Begin(); iter.hasNext(); iter.Next()) {cout << "value:" << iter.m_current->m_data << endl;}
}