反向迭代器

本期我们以list和vector为基础,来实现反向迭代器,还没看过之前章节的同学建议先看看之前的

(24条消息) C++-----list_KLZUQ的博客-CSDN博客

(24条消息) C++-----vector_KLZUQ的博客-CSDN博客

我们先看list,反向迭代器和正向迭代器相比,++是像前走的,而--是向后走的

反向迭代器_第1张图片

我们推测,rend在起始位置的前一个,rbegin在最后一个位置 

我们再看看库里面是如何实现的,库里面使用了适配器模式

我们可以对正向迭代器进行封装进而得到反向迭代器,反向迭代器的++调用正向迭代器的--,--再调用++

 传一个正向迭代器,就可以适配出一个反向迭代器

这是vector的

这是list的 

我们看上面typedef reverse_iterator,对于vector,这里的iterator就是value_type*,对于list,就是__list_iterator

reverse_iterator在stl_iterator.h这个文件里

反向迭代器_第2张图片

 下面我们看一些关键的

反向迭代器_第3张图片

 反向迭代器_第4张图片

 反向迭代器_第5张图片

 和我们前面说的一样,++就是调用--,--就是调用++,但是解引用却不一样

对当前位置解引用时,是解引用的当前正向迭代器的前一个位置

 我们看begin和end

反向迭代器_第6张图片

再看rbegin和rend ,是用正向迭代器构造的

反向迭代器_第7张图片

所以我们前面的推测是错误的,它是这样的结构

 反向迭代器_第8张图片

对于vector是这样的 

这样设计是为了对称镜像,反向迭代器和正向迭代器是对称关系

反向迭代器_第9张图片

而当我们这样写代码时就会出现问题 

反向迭代器_第10张图片

此时的rit如果我们解引用就是随机值了,而且第一个值没有被访问到

所以解引用是当前的前一个位置

我们设计的适合,可以按库里面一样的方法设计,也可以换一个方法设计,解引用当前位置就行了,按照喜好即可

代码实现

    template
	struct ReverseIterator
	{
		typedef ReverseIterator < Iterator, Ref, Ptr> Self;
		Iterator _it;
		ReverseIterator(Iterator it)
			:_it(it)
		{}
		Ref operator*()
		{
			Iterator tmp = _it;
			return *(--tmp);
		}
		Ptr operator->()
		{
			return &(operator*());
		}
		Self& operator++()
		{
			--_it;
			return *this;
		}
		Self& operator--()
		{
			++_it;
			return *this;
		}
		bool operator!=(const Self& s)
		{
			return _it!=s._it;
		}
	};

我们这里简单实现一下

反向迭代器_第11张图片

 然后我们就可以在list里写出反向迭代器了

        reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

然后我们实现rbegin和rend

反向迭代器_第12张图片

我们测试一下 ,没有问题

最厉害的地方是适配器是可以各种适配,给谁的迭代器就可以变成谁的反向迭代器,比如我们这里把vector拷贝过来,这里就可以直接写vector的反向迭代器了

反向迭代器_第13张图片

  rbegin和rend也是直接拷贝过来就行

反向迭代器_第14张图片

测试一下,同样没有问题 

因为我们写的反向迭代器是一个模板,所以后面的容器我们都可以拿来适配

以上即为本期全部内容,希望大家可以有所收获

如有错误,还请指正

你可能感兴趣的:(c++,迭代器,反向迭代器,算法,数据结构)