赞
踩
作者:几冬雪来
时间:2023年10月16日
内容:C++——反向迭代器讲解
目录
在上一篇博客中我们讲解了优先级队列队列和仿函数的实现,在更早之前我们还学习了C++中迭代器的知识,而今天我们将借由迭代器来实现我们这节课要讲解到的知识——反向迭代器。
在一开始学习C++的时候我们就接触了迭代器,迭代器可谓是C++不可或缺的一个部分。而我们今天要讲解的反向迭代器,对比起传统的迭代器它多了反向二字,那么它们到底有什么区别呢?
迭代器和反向迭代器它们解引用的使用是相同的,不同的点是迭代器进行++操作是正向走,而反向迭代器++则是反方向倒着走的。
在编译器中对于反向迭代器的实现还分为list和vector。
这里我们就先讲解list反向迭代器的实现。
list实现反向迭代器的方法比较简单,因为++操作符从正向走被更改为了反向走。
因为反向迭代器就只是++和--发生了改变,所以这个地方我们可以直接拿list处的代码对里面的operator++和operator--进行修改即可。
就像我们上面的代码一样,因为正向迭代器和反向迭代器是相反的,因此在list中对operator++进行修改的话,只需要将它下一个位置的指向改变。
原来->_next,更改为了之后就是->_prev,这样子就是从指向下一个改为指向上一个。同样的,--也应该进行修改从->_prev修改为->_next。
最后再创建一个类,如此list的反向迭代器就实现了。
对比list直接修改指向不同,vector反向迭代器有它的实现方式。
vector实现反向迭代器要运用到封装的操作,在反向迭代器中封装适配出一个正向迭代器。反向迭代器的++就去调用正向迭代器的--,反向迭代器的--就去调用正向迭代器的++。
这就是我们反向迭代器代码的实现,iterator是正向迭代器,要将正向迭代器转变为反向迭代器的话。
我们就再创建一个类出来,里面的类型不是int或者double,而是iterator。
这样子就实现了封装的操作。同时要求实现反向迭代器的代码输出也是十分的容易。
像这里Iterator是我们的正向迭代器,要实现反向迭代器的话就需要一个类,在类里面用Iterator定义一个current。
在下面要实现++操作的话就去调用current的--操作,反之--操作就去调用++操作。这样子就可以实现反向迭代器了。
但是看代码中还有解引用的代码,它解引用的解引用当前正向迭代器的前一个位置。
那为什么说中国解引用是一个很重要的点呢?
在看反向迭代器的实现原理后,我们会画出这样的一幅图。
rbegin在最末尾的位置上,rbegin--直到碰到rend停止。但是实际底层代码并不是这样子实现的,接下来我们来看看底层是怎么样的。
这个就是底层的代码,可以看出来在底层代码中rbegin的位置并不是最后一个数据的位置而是在end那个位置。
那么这个时候我们的图就要更改为下面这种。
看上面的图我们可以明显的发现,反向迭代器中的end和begin交换了位置。原本正向迭代器的begin变成了rend,end变为了rbegin。
这个地方vector是这样,list的反向迭代器亦是如此。rend用begin构造,rbegin用end进行构造。
下面来书写list的数据。
在list中反向迭代器也遵循反向对称,反向对称顾名思义就是和正向迭代器成对称关系。
但是这里就出现了一些问题,如果我们还是按照原先遍历的方式去遍历数组的话,从rbegin开始到rend结束,这就导致了rbegin一开始遍历的时候是一个随机值,最后到rend结束,但是也不会去访问rend里面的数据。
为了解决这个问题,这里就运用到了解引用。每次解引用都是解引用的前一个位置,也就是解引用在这里进行了一个错位的操作。
这样就不会出现访问到随机数和有一个数据没有陪访问到的特殊情况了。
- namespace bit
- {
- template<class Interator,class Ref,class Ptr>
- struct RI
- {
- Interator _it;
- PI(Interator _it)
- :_it(it);
- {
-
- }
-
- Ref operator*()
- {
- Interator tmp = _it;
- return *(--tmp)
- }
-
- Ptr operator->()
- {
- return &(operator*());
- }
-
- RI& operator++()
- {
- --_it;
- return *this;
- }
-
- RI& operator--()
- {
- ++_it;
- return *this;
- }
-
- bool operator!=(const RI& s) const
- {
- return _it != s._it;
- }
- };
- }
到这里我们的反向迭代器的知识就讲解完了,在结束了反向迭代器之后,接下来学习的C++的内容对比起我们现在学习的知识,难度有一定的上升。希望同学们可以顶住强度继续向前,同时也希望这篇博客能带来帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。