5.4 迭代器模式 Iterator (行为模式)

来源:互联网 发布:excel 两列数据相同项 编辑:程序博客网 时间:2024/05/20 16:12
1.  Iterator 迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示,又称游标(Cursor)。该模式的应用应该十分熟悉了,C++ 标准库 STL 中不同的容器都提供了相同的迭代器接口。这一模式的关键思想是将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器(iterator)对象中。迭代器类定义了一个访问列表元素的接口,迭代器对象负责跟踪当前的元素,即它知道哪些元素已经遍历过了。

   Iterator 适用于:1.访问一个聚合对象的内容而无需暴露它的内部表示。2.支持对聚合对象的多种遍历。3.对遍历不同的聚合结构提供一个统一的接口(即,支持多态迭代)。

2.结构图


3.注意事项

1)谁控制迭代器,不由客户控制迭代时,称为外部迭代器(external iterator),而当由迭代器控制时,称为内部迭代器(internal iterator)。使用外部迭代器,客户必须主动推进遍历的步伐,显式地向迭代器请求下一个元素。相反,使用内部迭代器时,客户只需提交一个执行请求,而迭代器将对聚合中的每一个元素实施该操作。 外部迭代器比内部迭代器更灵活。

2)谁定义遍历算法,聚合本身可以定义遍历算法,并在遍历过程中用迭代器来存储当前迭代的状态,这种迭代器称为一个游标,因为它仅用来指示当前位置。如果由迭代器负责遍历算法,那么将易于在相同的聚合上使用不同的迭代算法,同时也易于在不同的聚合上重用相同的算法。但同时,将遍历算法放入迭代器中会破坏聚合的封装性。

3)迭代器的健壮性非常重要,一个健壮的迭代器(robust iterator)保证插入和删除操作不会干扰遍历,且不需拷贝该聚合。不过有时还是很难做到。

4)在 C++ 中使用多态的迭代器,使用多态迭代器是有代价的。它们要求用一个 Factory Method 动态的分配迭代器对象。因此仅当必须多态时才使用它们,否则使用在栈中分配内存的具体的迭代器。多态迭代器有另一个缺点:客户必须负责删除它们。Proxy 为此提供了一种补救方法,我们可以使用一个栈分配的 Proxy 作为实际迭代器的中间代理。该代理在其析构器中删除该迭代器。这样当该代理生命周期结束时,实际迭代器将同它一起释放,即使在发生异常时,该代理机制能保证正确地清除迭代器对象,这就是著名的C++“资源分配即初始化”技术的一个应用。

5)空迭代器,一个空迭代器(Null Iterator)是一个退化的迭代器,它有助于处理边界条件。一个 NullIterator 总是已经完成了遍历,即它的 IsDone 操作总是返回 true。等还有其它比较复杂的注意事项。