Interator 迭代器

std::map<UniqueSessionId, ServerSession*>::iterator iter = ss_map.begin();


迭代器模式由以下角色组成:

1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。

2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。

3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。

4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色与该容器的结构相关。


迭代器模式给容器的应用带来以下好处:

1) 支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别。

2) 简化了容器的接口。但是在java Collection中为了提高可扩展性,容器还是提供了遍历的接口。

3) 对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的。


由此也能得出迭代器模式的适用范围:

1) 访问一个容器对象的内容而无需暴露它的内部表示。

2) 支持对容器对象的多种遍历。

3) 为遍历不同的容器结构提供一个统一的接口(多态迭代)。


Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

或者这样说可能更容易理解:

Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由Iterator提供的方法)访问聚合对象中的各个元素。


由于Iterator模式的以上特性:与聚合对象耦合,在一定程度上限制了它的广泛运用,一般仅用于底层聚合支持类,如STL的list、vector、stack等容器类及ostream_iterator等扩展iterator。


根据STL中的分类,Iterator包括:

输入迭代器(Input Iterator):通过对输入迭代器解除引用,它将引用对象,而对象可能位于集合中。最严格的输入迭代只能以只读方式访问对象。

输出迭代器(Output Iterator):该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。


以上两种基本迭代器可进一步分为三类

前向迭代器(Forward Iterator):该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input Iterator的所有特性,和Output Iterator的部分特性,以及单步向前迭代元素的能力。

双向迭代器(Bidirectional Iterator):该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。

随机迭代器(Random Access Iterator):该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。

vector 和deque提供的是RandomAccessIterator,list提供的是BidirectionalIterator,set和map提供的 iterators是 ForwardIterator。


Iterator模式有三个重要的作用:

1)它支持以不同的方式遍历一个聚合 复杂的聚合可用多种方式进行遍历,如二叉树的遍历,可以采用前序、中序或后序遍历。迭代器模式使得改变遍历算法变得很容易:仅需用一个不同的迭代器的实例代替原先的实例即可,你也可以自己定义迭代器的子类以支持新的遍历,或者可以在遍历中增加一些逻辑,如有条件的遍历等。

2)迭代器简化了聚合的接口 有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口了,这样就简化了聚合的接口。

3)在同一个聚合上可以有多个遍历 每个迭代器保持它自己的遍历状态,因此你可以同时进行多个遍历。

此外,Iterator模式可以为遍历不同的聚合结构(需拥有相同的基类)提供一个统一的接口,即支持多态迭代。


简单说来,迭代器模式也是Delegate原则的一个应用,它将对集合进行遍历的功能封装成独立的Iterator,不但简化了集合的接口,也使得修改、增 加遍历方式变得简单。从这一点讲,该模式与Bridge模式、Strategy模式有一定的相似性,但Iterator模式所讨论的问题与集合密切相关, 造成在Iterator在实现上具有一定的特殊性,具体将在示例部分进行讨论。


与集合密切相关,限制了 Iterator模式的广泛使用。在一般的底层集合支持类中,我们往往不愿“避轻就重”将集合设计成集合 + Iterator 的形式,而是将遍历的功能直接交由集合完成,以免犯了“过度设计”的诟病,但是,如果我们的集合类确实需要支持多种遍历方式(仅此一点仍不一定需要考虑 Iterator模式,直接交由集合完成往往更方便),或者,为了与系统提供或使用的其它机制,如STL算法,保持一致时,Iterator模式才值得考虑。

C++中的迭代器iterator)是标准库中用于遍历容器元素的重要机制。它提供了一种统一的接口,使得不同类型的容器(如`vector`、`list`、`map`等)可以通过相同的编程模式进行访问和操作。理解迭代器的概念及其使用方式对于编写高效且可维护的代码至关重要。 ### 迭代器的基本概念 在C++中,迭代器是一种类似于指针的对象,它可以用来访问容器中的元素,并支持基本的指针操作,如解引用(`*it`)和递增(`++it`)。每种容器都提供了自己的迭代器类型,这些类型通常定义为容器类的嵌套类型。 C++标准库定义了五种主要的迭代器类别: 1. **输入迭代器(Input Iterator)**:只读、单向移动,适用于一次遍历。 2. **输出迭代器(Output Iterator)**:只写、单向移动,常用于算法的输出目标。 3. **前向迭代器(Forward Iterator)**:可读写、单向移动,支持多次遍历。 4. **双向迭代器(Bidirectional Iterator)**:可读写、双向移动,支持向前和向后遍历。 5. **随机访问迭代器(Random Access Iterator)**:支持所有指针操作,包括加减整数偏移量、比较等,适用于快速访问。 ### 迭代器的使用方法 大多数STL容器都提供了`begin()`和`end()`成员函数,分别返回指向容器第一个元素和最后一个元素之后位置的迭代器。例如: ```cpp #include <iostream> #include <vector> int main() { std::vector<int> vec = {1, 2, 3, 4, 5}; for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; return 0; } ``` 上述代码展示了如何使用`vector`的迭代器来遍历其元素。注意循环条件是`it != vec.end()`,而不是`it <= vec.end()`,因为并非所有迭代器都支持小于或等于操作。 除了普通迭代器外,C++还提供了反向迭代器(reverse iterator),通过`rbegin()`和`rend()`获取,允许从后往前遍历容器。 ### 迭代器的实现细节 从底层来看,迭代器的实现依赖于容器的具体数据结构。例如,`vector`的迭代器本质上是指针,因为它内部使用连续内存存储元素;而`list`的迭代器则是一个封装了节点指针的对象,因为链表结构需要通过节点间的链接进行遍历。 为了支持不同的操作语义,迭代器通常会重载以下运算符: - `*` 和 `->`:用于访问当前所指元素。 - `++` 和 `--`:用于移动到下一个或上一个元素。 - `==` 和 `!=`:用于比较两个迭代器是否指向相同的位置。 - 对于随机访问迭代器,还会重载`+`、`-`、`<`、`<=`、`>`、`>=`等运算符。 此外,迭代器失效(iterator invalidation)是一个需要注意的问题。当容器执行某些操作(如插入、删除、扩容),原有的迭代器可能变得无效,继续使用会导致未定义行为。因此,在修改容器后应重新获取迭代器或采取适当的措施避免失效问题。 ### 特殊类型的迭代器 C++标准库还提供了一些特殊的迭代器,用于特定用途: - **插入迭代器(Insert Iterator)**:如`back_inserter`、`front_inserter`和`inserter`,它们可以自动调用容器的插入方法,将赋值操作转换为插入操作。 ```cpp #include <algorithm> #include <vector> #include <list> int main() { std::vector<int> vec = {1, 2, 3}; std::list<int> lst; std::copy(vec.begin(), vec.end(), std::back_inserter(lst)); // lst now contains {1, 2, 3} return 0; } ``` - **流迭代器(Stream Iterator)**:如`std::istream_iterator`和`std::ostream_iterator`,它们允许将输入/输出流视为容器进行操作。 ```cpp #include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> vec(std::istream_iterator<int>(std::cin), std::istream_iterator<int>()); std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; return 0; } ``` - **移动迭代器(Move Iterator)**:通过`std::make_move_iterator`创建,用于在复制或移动操作中启用移动语义,提高性能[^1]。 ### 总结 迭代器是C++标准库的核心组成部分之一,它不仅简化了容器的遍历操作,也为泛型编程奠定了基础。掌握不同类型的迭代器及其适用场景,有助于编写更加灵活和高效的代码。同,了解迭代器的实现原理可以帮助开发者更好地理解底层机制,从而做出更优的设计决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值