迭代器修改元素_C++ STL六大组件4Iterator(迭代器)

a47200b0d5b93fa4d05a7acb19595d30.png

C++ STL 迭代器

STL概述的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得算法变得非常通用。例如,由于函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组。

在C++ STL 中,对容器中数据的读和写,是通过迭代器完成的,扮演着容器和算法之间的胶合剂。只要容器提供迭代器的接口,同一套算法代码可以利用在完全不同的容器中,这是抽象思想的经典应用。

迭代器(iterator)是一种检查容器内元素并遍历元素的数据类型。

  • 每种容器类型都定义了自己的迭代器类型。

  • 通过迭代器只能读取容器中的元素,而不能修改。

  • iterator除了进行++, --操作,可以将iter+n, iter-n赋给一个新的iteraor对象。还可以使用一个iterator减去另外一个iterator。

常见的迭代器类型:

  • iterator

  • const_iterator

  • reverse_iterator 

  • const_reverse_iterator

迭代器的实现原理

迭代器的作用就是提供一个遍历容器内部所有元素的接口。

因此迭代器的内部必须保存一个与容器相关联的指针,然后重载各种运算操作来方便遍历。

实际上这和C++标准库中的智能指针很像。智能指针也是将一个指针封装,然后通过引用计数或是其它方法完成自动释放内存的功能。

为了达到和原有指针一样的功能,也需要对*,->等运算符进行重载。

下面参照智能指针实现了一个简单vector的迭代器。

vecIter主要作用就是包裹一个指针。不同容器内部数据结构不相同,因此迭代器操作符重载的实现也会不同。

比如++操作符,对于线性分配内存的数组来说,直接对指针执行++操作即可。但是如果容器是List就需要采用元素内部的方法,比如ptr->next()之类的方法访问下一个元素。

因此,STL容器都实现了自己的专属迭代器。

templateclass vecIter{    Item *ptr;public:    typedef std::forward_iterator_tag iterator_category;    typedef Item value_type;    typedef Item* pointer;    typedef Item& reference;    typedef std::ptrdiff_t difference_type;public:    vecIter(Item *p = 0) :ptr(p){}    Item& operator*()const{        return *ptr;    }    Item* operator->()const{        return ptr;    }    //pre    vecIter& operator++(){        ++ptr;        return *this;    }    vecIter operator++(int){        vecIter tmp = *this;        ++*this;        return tmp;    }    bool operator==(const vecIter &iter){        return ptr == iter.ptr;    }    bool operator!=(const vecIter &iter){        return !(*this == iter);    }};

迭代器特性分类

对于迭代器来说,是否有针对不同特性迭代器的优化方法呢?

答案是肯定的。

拿一个STL算法库中的distance函数来说。distance函数接受两个迭代器参数,然后计算他们两者之间的距离。

显然对于不同的迭代器计算效率差别很大。

比如对于vector容器来说,由于内存是连续分配的。因此指针直接相减即可获得两者的距离。

而list容器是链式表,内存一般都不是连续分配。因此只能通过一级一级调用next()或其他函数,每调用一次再判断迭代器是否相等来计算距离。

vector迭代器计算distance的效率为O(1),而list则为O(n),n为距离的大小。

因此,根据迭代器不同的特性,将迭代器分为5类:

Input

Iterator

所指的对象为只读的。

Output

Iterator

所指对象只能进行一次写入操作。

Forward

Iterator

允许”读写型”算法在迭代器区间内进行读写操作,比如说replace函数需要读取区间内容,根据所读内容决定是否写入。

Bidirectional

Iterator

可双向移动。某些算法需要反向遍历某个迭代器区间。

Random

Access

Iterator

前四种迭代器只提供部分指针算数能力(前三种支持++运算符,后一种还支持–运算符),第五种则支持所有指针的算术运算,包括p+n, p-n, p[n], p1-p2, p1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值