C++迭代器

来源:互联网 发布:java spring 单例模式 编辑:程序博客网 时间:2024/06/16 03:47

所有标准库容器都支持迭代器,只有少数几种支持下标运算符如string和vector。迭代器有有效和无效之分,和指针差不多,有效的迭代器或者指向某个元素或者指向容器中尾元素的下一位置,其他所有情况都是无效。

使用迭代器

获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员,如:

vector<int> v = {1, 2, 3};auto a = v.begin(), e = v.end();

begin成员返回指向容器的第一个元素的迭代器,而end成员返回指向容器“尾元素的下一个位置”的迭代器,即为一个容器本不存在的尾后元素,没有什么实际含义仅是一个标记,表示已经处理完容器中的所有元素。end成员返回的迭代器常被称作尾后迭代器(off-the-end iterator)或者尾迭代器(end iterator)。特殊情况下如果容器为空,则begin和end返回的是同一个迭代器。

迭代器运算符

有如下一些运算(部分):

*iter                       //返回迭代器所指元素的引用,iter必须合法并确实指向某个元素iter->mem                   //解引用iter并取得该元素名为mem的成员,等价于(*iter).mem++iter                      //令iter指向容器中的下一个元素--iter                      //令iter指向容器中的前一个元素iter1 == iter2              //判断两个迭代器是否相等,即是否指向同一个元素iter1 != iter2

可以使用++或者–将迭代器从一个元素移到另一个元素。
因为end返回的迭代器并不实际指向某个元素,所以不可以对其进行递增或者解引用操作。
所有标准库容器的迭代器都定义了==和!=,但是它们中的大多数都没有定义<运算符。

迭代器类型

拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器类型:

vector<int>::iterator it;string::iterator it2;vector<int>::const_iterator it3;string::const_iterator it4;

const_iterator和指向常量的指针差不多,能读取但不能修改它所指的元素值。如果vector对象或者string对象是一个常量,只能使用const_iterator,如果不是常量,则const_iterator和iterator都可以。

begin和end运算符

begin和end运算符返回的具体类型由对象是否是常量来决定的,如果对象是常量。begin和end返回const_iterator,如果对象不是常量,则返回iterator。
C++11新标准引入了两个新函数,分别是cbegin和cend,类似于begin和end,只不过不论对象是否是常量,返回值都是const_iterator。

解引用和成员访问操作

解引用迭代器可获得迭代器所指的对象,如果该对象类型恰好是类,则可能可以访问它的成员。如:

(*it).empty();

其表达式含义是,先对it解引用,然后对解引用的结果再执行点运算符,必须加括号,如果不加,则点运算符由it来执行,而非it解引用的结果。

(*it).empty();          //正确*it.empty();            //错误

C++定义了箭头运算符(->)把解引用和成员访问两个操作结合起来,即it->mem与(*it).mem含义相同。

某些对vector对象的操作回使迭代器失效

任何一种可能改变vector对象容量的操作比如push_back,都会使该vector对象的迭代器失效。但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。

迭代器运算

string和vector的迭代器提供了更多额外的运算符,如:

iter + n                //迭代器加上一个整数值仍是一个迭代器,新位置与原来相比向前移动了n个元素,结果迭代器或者指示容器内一个元素,或者指示容器尾元素的下一个位置iter - n                //迭代器减去一个整数值仍是一个迭代器,新位置与原来相比向后移动了n个元素,结果迭代器或者指示容器内一个元素,或者指示容器尾元素的下一个位置iter1 += n              //迭代器加法的复合赋值语句iter1 -= n              //迭代器剪发的复合赋值语句iter1 - iter2           //结果是它们之间的距离,即将运算符右侧的迭代器向前移动差值个元素后将得到左侧的迭代器,参与运算的两个迭代器必须指向的是同一个容器中的元素或者尾元素的下一个位置>, >=, <, <=            //迭代器的关系运算符,如果某迭代器指向的容器位置在另一个迭代器所指的位置之前,则说前者小于后者,参与运算的两个迭代器必须指向的是同一个容器中的元素或者尾元素的下一个位置

只要两个迭代器指向的是同一容器中的元素或者尾元素的下一个位置,就能将其相减,所得结果是两个迭代器的距离,其类型是名为difference_type的带符号整数,string和vector都定义了difference_type,因为这个距离可正可负,所以difference_type是带符号类型的。