您的位置:首页 > 其它

STL源码学习----迭代器及其适配器

2012-04-17 23:08 357 查看
  “迭代器是连接容器和算法的纽带,它们为数据提供了一种抽象的观点,使写算法的人不必关心多种多样的数据结构的具体细节。”-----<C++程序设计语言>

  SGI STL 3.3中的stl_iterator_base.h 和stl_iterator.h两个头文件中定义了跟迭代器相关的一些类。本文首先会介绍迭代器的基本概念,然后分析与迭代器相关的五种类型及traits(萃取)方法,最后简要介绍迭代器的几种适配器。

1,迭代器概述

  迭代器是指向序列元素的指针的一种抽象。通过使用迭代器,我们可以访问序列中的某个元素、改变序列中的某个元素的值、使迭代器向前或向后行走等等。

  依据有效执行操作的情况,迭代器可以分为五类:输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机存取迭代器。STL中用五个类来代表这五种迭代器类别:

  其中

  · Input Iterator 所指的对象不允许外界改变

  · Output Iterator 支持对该迭代器所指对象的写操作

  · Forward Iterator 不仅支持Input Iterator和Output Iterator的操作,还能在序列中前向移动指向下一个元素

  · Bidirectional Iterator 可以双向移动,既可指向序列中的下一个元素,也可以指向序列中的前一个元素

  · Random Iterator 既可以双向移动,又可以跨越多个元素存取对象

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};


从上面的代码中可以看出,五种类型的迭代器有如下的层次结构:

ostream_iterator的实现

template <class _Tp,
class _CharT = char, class _Traits = char_traits<_CharT> >
class ostream_iterator {
public:
typedef _CharT                         char_type;
typedef _Traits                        traits_type;
typedef basic_ostream<_CharT, _Traits> ostream_type;

typedef output_iterator_tag            iterator_category;
typedef void                           value_type;
typedef void                           difference_type;
typedef void                           pointer;
typedef void                           reference;

ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
ostream_iterator(ostream_type& __s, const _CharT* __c)
: _M_stream(&__s), _M_string(__c)  {}
ostream_iterator<_Tp>& operator=(const _Tp& __value) {
*_M_stream << __value;
if (_M_string) *_M_stream << _M_string;
return *this;
}
ostream_iterator<_Tp>& operator*() { return *this; }
ostream_iterator<_Tp>& operator++() { return *this; }
ostream_iterator<_Tp>& operator++(int) { return *this; }
private:
ostream_type* _M_stream;
const _CharT* _M_string;
};


  用户可以像下面一样使用ostream_iterator:

ostream_iterator<string> os(cout);
*++os = "cobb";
*os = "liu";


  上面的这段程序会产生输出cobbliu。在使用ostream_iterator的时候需要像使用正常迭代器一样将迭代器作迭代操作(++)。

  istream_iterator的实现跟ostream_iterator的实现大相径庭,值得注意的是istream_iterator中有一个标志标识输入序列是否结束,它的默认构造函数会将istream_iterator指向输入序列的结束位置(M_ok=false),表示输入序列结束。当对输入迭代器作迭代操作(++)的时候,会判断M_ok的值,如果该值为false,则终止读过程。

  

  istreambuf_iterator和ostreambuf_iterator可以使用户跨过iostream,直接跟流缓冲区打交道。

4,总结

  迭代器将算法和数据结构有效地分离并粘合起来。实际上,STL中的很多容器都设计有自己专属的迭代器,因为只有它自己才能知道自身数据结构的布局及其遍历方法,只需要按照标准声明上面提到的五种迭代器要用到的数据类型即可。迭代器更多的是运用到算法中,有了泛型和迭代器的支持,算法可以达到很高的内聚性。

5,参考资料

  1)《STL源码剖析》 侯捷著

  2) SGI STL 3.3源代码

  3)《C++程序设计语言》 Bjarne Stroustrip先生。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: