迭代器:除了在其它语言中司空见惯的下标法访问容器元素之外,C++语言提供了一种全新的方法——迭代器(iterator)来访问容器的元素。迭代器其实类似于引用,指向容器中某一元素。换个方式来说,容器就是数据结构的泛指,迭代器就是指针的泛指,可以指向元素。容器相当于一个储藏柜,里面装的许多不同的物品就像是储存的元素,比如面包、啤酒、苹果、现金。要取得各个物体就得用与各个物体向匹配的工具,如取出面包要用盘子、取出啤酒要用杯子、取出苹果要用篮子、取出现金要用钱包。迭代器的作用就相当于取出物品的工具的抽象,通过迭代器泛指现实生活中从贮藏室中取出物体的工具。C++迭代器是一种检查容器内元素并遍历元素的数据类型。

迭代器的类型

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

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

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

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

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

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

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

指针迭代器

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

 #include <iostream.h>
#include <algorithm> using namespace std;
#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 ;
}

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

iarray[20] = 50;

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

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

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

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

 #include <iostream.h>
#include <algorithm>
#include <vector> using namespace std;
vector<int> intVector(); void main()
{
intVector[] = ;
vector<int>::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;
}

常量迭代器

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

vector<int>::iterator first;

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

first = intVector.begin();

*first = 123;

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

const vector<int>::iterator result;

result = find(intVector.begin(), intVector.end(), value);

if (result != intVector.end())

*result = 123;  // ???

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

具体迭代器的实现源码,https://www.sgi.com/tech/stl/download.html上有,可以自己下来看看。

STL六大组件之——迭代器这个东西的更多相关文章

  1. STL —— STL六大组件

    注:以下内容摘自 http://blog.csdn.net/byxdaz/article/details/4633826 STL六大组件 容器(Container) 算法(Algorithm) 迭代器 ...

  2. STL 六大组件 功能与运用

    STL 提供六大组件,彼此可以组合套用: 1 容器(containers):各种数据结构,如vector,list,deque,set,map,用来存放数据,从实现的角度来看,STL容器是一种clas ...

  3. STL六大组件之——分配器(内存分配,好深奥的东西)

    SGI设计了双层级配置器,第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器:当配置区小于1 ...

  4. [转贴]从零开始学C++之STL(一):STL六大组件简介

    一.STL简介 (一).泛型程序设计 泛型编程(generic programming) 将程序写得尽可能通用 将算法从数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 (二 ...

  5. STL六大组件简介

    一.STL简介 (一).泛型程序设计 泛型编程(generic programming) 将程序写得尽可能通用 将算法从数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 (二 ...

  6. STL六大组件之——适配器代表大会

    适配器也是一种常用的设计模式: 将一个类的接口转换为另一个类的接口,使得原本因接口不兼容而不能合作的两个类可以一起运作.STL提供三种适配器:改变容器接口的容器适配器.改变迭代器接口的迭代器适配器以及 ...

  7. STL六大组件之——算法小小小小的解析

    参考自侯捷的<stl源码剖析> stl算法主要分为非可变序列算法(指不直接修改其所操作的容器内容的算法),可变序列算法(指可以修改它们所操作的容器内容的算法),排序算法(包括对序列进行排序 ...

  8. STL六大组件之——容器知识大扫盲

    STL中的容器主要涉及顺序容器类型:vector.list.deque,顺序容器适配器类型:stack.queue.priority_queue.标准库中的容器分为顺序容器和关联容器.顺序容器(seq ...

  9. STL六大组件

    1.容器 顺序容器.关联容器 2.算法 各种常用算法,sort.search.copy…… 3.迭代器 用来索引容器中元素,是容器与算法之间的胶合剂 4.仿函数(另名函数对象) 仿函数就是让一个类的使 ...

随机推荐

  1. 给 Gradle 配置国内的 Maven 仓库,提高 jar 包下载速度。

    最近使用 gradle 跑一些 spring 的示例,在下载一些 jar 的时候速度特别慢,因为是访问的国外的 maven 仓库. 开源中国提供了国内的 maven 库,所以可以在 gradle 里设 ...

  2. 获取sde 工作空间 propertys

    // This example shows how to inspect and display different types of properties for a workspace. publ ...

  3. javascript中对象的属性的特性

    1.ES5的属性特性包括下面六个: configurable: 表示能否通过delete来删除属性从而重新定义属性,能够修改属性的特性,默认为true enumberable: 表示是否能通过for- ...

  4. AngularJs-ui modal 封装 dialog

    常常在操作中和用户进行交互,及时反馈操作结果:用到alert 和confrim 功能 找到一个基于anguarjs-ui的modal,方便我们使用 angular-dialog-service 注意要 ...

  5. Java 异常 —— Bad version number in .class file

    把一个项目拷贝到另一个环境,运行时报错: Caused by: java.lang.UnsupportedClassVersionError: Bad version number in .class ...

  6. 在windows系统上安装VMware Workstation虚拟机,然后在虚拟机VMware Workstation上安装linux系统,在linux系统安装xshell的服务端,在windows系统上安装xshell。用windows系统上的xshell连接到linux

    第一步:安装xshell: 去百度   xshell ,然后安装一下就可以了.就是普通的软件安装,在这里不做过多的接收. 第二步:安装虚拟机VMware Workstation 百度安装,不做过介绍 ...

  7. vim编辑器配置

    原文链接:https://github.com/ma6174/vim http://my.oschina.net/swuly302/blog/156784?fromerr=itaFZFMb https ...

  8. NDK(1)配置ndk,含eclipse,Android Studio1.5.1

    现在的ndk配置已经非常简单,如果看到要cygwin的请关闭. 1,Eclipse 添加ndk linux,mac ,windows 相似, a.下载 ndk并解压, b.在eclipse的andro ...

  9. 【Android】MTK Android 编译命令

    命令格式:./maketek [option] [project] [action] [modules] Option: -t ,-tee :输出log信息到当前终端 -o , -opt=-- : 编 ...

  10. LBS由ip查经纬度

    LBS API: https://api.map.baidu.com/highacciploc/v1?qcip=223.104.5.201&qterm=pc&ak=NLwCqrDce4 ...