1. 情景与意图
在STL的六大组件中,其中一个组件就是 迭代器。可见迭代器的使用场景和作用都是非常大的,在STL的容器中都实现了自己的迭代器。迭代器,顾名思义,就是和为了方便遍历而提供的一中手段,我们对于自己实现的容器或者其他对象,应该怎样设计自己的迭代器呢?——迭代器设计模式。
2. 迭代器模式
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
就是不暴露对象细节的情境下,提供以恶搞顺序遍历的手段。下面通过一个简单的容器来实现一下。如果要看更详细的迭代器实现,可以关注之前的一篇文章【STL的list】
3. 容器迭代器
为了面向对象的首先迭代器,我们先定义一个迭代器的基类。
!!!注意!!!其实,大部分语言对于迭代器,并不会用面向对象的方式实现,而是针对自己特定容器实现特定的迭代器即可。这里为了演示,通过面向对象的方式。
template <class T>
class DPIterator {
public:
virtual T& next() = 0;
virtual T& current() = 0;
};
下面来实现一个具体的迭代器的类。
// 这是我们容器的结点类
typedef struct DPNode {
std::string _val;
DPNode* _next;
};
// 迭代器容器
class DPContainerIterator : public DPIterator<DPNode*> {
DPNode* _node;
public:
DPContainerIterator(DPNode* node)
:_node(node) {}
DPNode*& next() {
return _node->_next;
}
DPNode*& current() {
return _node;
}
/*包括 ++ 、->、* != 等一系列操作都应该实现*/
};
下面看看我们特定的容器实现
class DPContainer {
DPNode* _head;
public:
DPContainerIterator begin() {
return DPContainerIterator(_head->_next);
}
DPContainerIterator end() {
return DPContainerIterator(_head);
}
/*大部分时候,可能会用到这种 itertor.begin() != itertor.end() 判断条件*/
/*这个时候就需要对上面的迭代器容器进行 != 符号重写*/
};
4. 总结
迭代器方便我们自定义容器的遍历,它分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
迭代器设计模式是非常常用的设计模式,建议熟练掌握。
C++实现迭代器模式代码:【迭代器模式C++源码】