迭代器

迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。

迭代器有各种不同的创建方法。程序可能把迭代器作为一个变量创建。一个STL容器类可能为了使用一个特定类型的数据而创建一个迭代器。作为指针,必须能够使用*操作符类获取数据。你还可以使用其他数学操作符如++。典型的,++操作符用来递增迭代器,以访问容器中的下一个对象。如果迭代器到达了容器中的最后一个元素的后面,则迭代器变成past-the-end值。使用一个past-the-end值得指针来访问对象是非法的,就好像使用NULL或为初始化的指针一样。

提示

STL不保证可以从另一个迭代器来抵达一个迭代器。例如,当对一个集合中的对象排序时,如果你在不同的结构中指定了两个迭代器,第二个迭代器无法从第一个迭代器抵达,此时程序注定要失败。这是STL灵活性的一个代价。STL不保证检测毫无道理的错误。

迭代器的类型

对于STL数据结构和算法,你可以使用五种迭代器。下面简要说明了这五种类型:

·        Input iterators 提供对数据的只读访问。

·        Output iterators 提供对数据的只写访问

·        Forward iterators 提供读写操作,并能向前推进迭代器。

·        Bidirectional iterators提供读写操作,并能向前和向后操作。

·        Random access iterators提供读写操作,并能在数据中随机移动。

尽管各种不同的STL实现细节方面有所不同,还是可以将上面的迭代器想象为一种类继承关系。从这个意义上说,下面的迭代器继承自上面的迭代器。由于这种继承关系,你可以将一个Forward迭代器作为一个output或input迭代器使用。同样,如果一个算法要求是一个bidirectional 迭代器,那么只能使用该种类型和随机访问迭代器。

指针迭代器

正如下面的小程序显示的,一个指针也是一种迭代器。该程序同样显示了STL的一个主要特性——它不只是能够用于它自己的类类型,而且也能用于任何C或C++类型。Listing 1, iterdemo.cpp, 显示了如何把指针作为迭代器用于STL的find()算法来搜索普通的数组。

 1. iterdemo.cpp

 #define SIZE 100
int iarray[SIZE]; int main()
{
iarray[] = ;
int* ip = find(iarray, iarray + SIZE, );
if (ip == iarray + SIZE)
cout << "50 not found in array" << endl;
else
cout << *ip << " found in array" << endl;
return ;
}

在引用了I/O流库和STL算法头文件(注意没有.h后缀),该程序告诉编译器使用std名字空间。使用std名字空间的这行是可选的,因为可以删除该行对于这么一个小程序来说不会导致名字冲突。

程序中定义了尺寸为SIZE的全局数组。由于是全局变量,所以运行时数组自动初始化为零。下面的语句将在索引20位置处地元素设置为50,并使用find()算法来搜索值50:

iarray[] = ;

int* ip = find(iarray, iarray + SIZE, );

find()函数接受三个参数。头两个定义了搜索的范围。由于C和C++数组等同于指针,表达式iarray指向数组的第一个元素。而第二个参数iarray + SIZE等同于past-the-end 值,也就是数组中最后一个元素的后面位置(也就是说迭代器end的值是不存在的)。第三个参数是待定位的值,也就是50。find()函数返回和前两个参数相同类型的迭代器,这儿是一个指向整数的指针ip。

提示

必须记住STL使用模板。因此,STL函数自动根据它们使用的数据类型来构造。

为了判断find()是否成功,例子中测试ip和 past-the-end 值是否相等:

if (ip == iarray + SIZE) ...

如果表达式为真,则表示在搜索的范围内没有指定的值。否则就是指向一个合法对象的指针,这时可以用下面的语句显示::

cout << *ip << " found in array" << endl;

测试函数返回值和NULL是否相等是不正确的。不要象下面这样使用:

int* ip = find(iarray, iarray + SIZE, 50);
if (ip != NULL) ...  // ??? incorrect

当使用STL函数时,只能测试ip是否和past-the-end 值是否相等。尽管在本例中ip是一个C++指针,其用法也必须符合STL迭代器的规则。

容器迭代器

尽管C++指针也是迭代器,但用的更多的是容器迭代器。容器迭代器用法和iterdemo.cpp一样,但和将迭代器申明为指针变量不同的是,你可以使用容器类方法来获取迭代器对象。两个典型的容器类方法是begin()和end()。它们在大多数容器中表示整个容器范围。其他一些容器还使用rbegin()和rend()方法提供反向迭代器,以按反向顺序指定对象范围。

下面的程序创建了一个矢量容器(STL的和数组等价的对象),并使用迭代器在其中搜索。该程序和前一章中的程序相同。

Listing 2. vectdemo.cpp

 vector intVector();

 void main()
{
intVector[] = ;
vector::iterator intIter =find(intVector.begin(), intVector.end(), );
if (intIter != intVector.end())
cout << "Vector contains value " << *intIter << endl;
else
cout << "Vector does not contain 50" << endl;
}

注意用下面的方法显示搜索到的数据:

cout << "Vector contains value " << *intIter << endl;

常量迭代器

和指针一样,你可以给一个迭代器赋值。例如,首先申明一个迭代器:

vector::iterator first;

该语句创建了一个vector类的迭代器。下面的语句将该迭代器设置到intVector的第一个对象,并将它指向的对象值设置为123::

first = intVector.begin();
*first = 123;

这种赋值对于大多数容器类都是允许的,除了只读变量。为了防止错误赋值,可以申明迭代器为:

const vector::iterator result;
result = find(intVector.begin(), intVector.end(), value);
if (result != intVector.end())
  *result = 123;  // ???

警告

另一种防止数据被改变得方法是将容器申明为const类型。

转载自:http://blog.chinaunix.net/uid-20773165-id-1847758.html。

C++STL之迭代器的更多相关文章

  1. STL的迭代器和类型萃取

    今天就可以把STL库中迭代器的实现,和类型萃取好好整理一下了 迭代器的设计思维是STL的关键所在,在STL的实际运用和泛型思维,迭代器都扮演着十分重要的角色,STL力求把数据容器和算法的概念分开来,于 ...

  2. 带你深入理解STL之迭代器和Traits技法

    在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...

  3. C++ 标准模板库(STL)——迭代器(iterators)的用法及理解

    C++ STL中迭代器(iterators)用于遍历对象集合的元素.由于容器大小随着插入删除等操作动态改变,无法像静态数组那样获取数组长度然后遍历容器里的所有元素:这时就需要迭代器,每次从容器内第一个 ...

  4. STL之迭代器(iterator)

    STL的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再用一帖粘着剂将它们撮合在一起.没错,这个粘着剂正是迭代器(iterator).迭代器的主要目的是通过遍历来对容器中元素进行相关操作.算法 ...

  5. C++STL之迭代器2

    在学习c++ STL的时候,整天碰到迭代器,也整天用,但是,到底它是个什么东西,很多人没有一个认识.这里我通过几个小的DEMO,来看看迭代器.首先我实现了一个十分简陋的vector类: templat ...

  6. STL容器迭代器失效分析

    连续内存序列容器(vector, string, deque) 对于连续内存序列STL容器,例如vector,string,deque,删除当前iterator会使得后面所有的iterator都失效, ...

  7. STL之迭代器

    容器支持的迭代器类型  STL Container  Type of Iterators Supported   vector  random access iterators 元素严格有序(类似数组 ...

  8. C++ STL中迭代器失效的问题

    my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...

  9. ###STL学习--迭代器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的迭代器. ###stl学习 |--迭代 ...

随机推荐

  1. [移动开发]全面理解UnityUI系统

    随着 Unity 4.6 发布,新 UI 系统终于与大家见面了. RectTransform Unity UI 系统使用 RectTransform 实现基本的布局和层次控制.RectTransfor ...

  2. C# 生成XML空元素/空节点自动换行解决方案

    使用DataSet可以直接输出XML,并可指定是否带有Schema: ds.WriteXml(XMLFile,XmlWriteMode.WriteSchema ) 不过,这样将不会输出值为Null的字 ...

  3. LGLProgressHUD

    不想用第三方的指示器,感觉有点大,自己写了一个简单的活动指示器,目前只有两种效果.效果如图 第一种: 第二种 第二种可以随着提示文字的增多而变长 LGLProgressHUD.h // // LGLP ...

  4. 在Windows下编写并运行第一个ASP.NET 5 Preview Web API程序

    2015年07月21日在微软中国MSDN的官方微博上得知Visual Studio 2015正式版完美发布. 抱着尝鲜的心态下载了Visual Studio社区版本. 在这个首发的版本里面,我们可以看 ...

  5. hdu 1518 拼正方形

    本题来自:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题意:输入几个长度,判断能否拼成正方形. 以下部分参考了网友代码,终于ac啦. #include ...

  6. Cookies简介和使用

    Cookie public class javax.servlet.http.Cookie  1作用(1)Cookie能使站点跟踪特定访问者的访问次数.最后访问时间和访问者进入站点的路径(2)Cook ...

  7. CentOS下apache绑定域名

    本文主要介绍在CentOS下apache绑定域名以及apache绑定多个域名,首先要找到apache的配置文件httpd.conf的位置.CentOS操作系统一般在 /etc/httpd/conf 下 ...

  8. SharePoint 2013 新功能探索 之 SPGroup、SPUser 事件处理程序 还要继续改进

    曾几何时,想要获取SPGroup Add及SPUserAdd事件,在网上查找各种方法,都没有找到相对应的解决办法,如今在VS 2013 Preview版本 提供了 SPSecurityEventRec ...

  9. android ArrayAdapter BaseAdapter SimpleAdapter使用讲解

    不是我针对谁,我只想针对新手玩家. 不清楚Adapter作用的可以看一下http://www.cnblogs.com/zhichaobouke/p/5798672.html (括号里的内容都是我主观添 ...

  10. SAP中关于用户IP信息的获取(转载)

    SAP中如何获取登录用户的IP? 或如何查看哪些IP登录到SAP中: 在Table: USR41中查看,具体字段的说明如下: MANDT   ---   ClientBNAME   ---   登录的 ...