【C++】Reverse_iterator

本文详细介绍了C++中反向迭代器的概念及其作用,通过对比vector和list的迭代器实现,阐述了反向迭代器在不连续内存结构如list中的必要性。并模拟实现了list和vector的反向迭代器,展示了如何通过反向迭代器进行正向减法操作,以及在实际代码中的应用。
摘要由CSDN通过智能技术生成

这篇文章通用于vector和list的反向迭代器,希望这篇文章看完你能对反向迭代器有更深的理解

---------

什么是反向迭代器

在遍历容器的时候,会有以下几种方式:

1.下标的随机访问,deque、vector和string都支持这种

2.迭代器

3.范围for

从底层来说,范围for其实就是迭代器经过包装之后的样子,这里主要说一下迭代器,这个使用的时候一般是如此使用:

 当然,如果熟悉一点,可以直接上auto

在之前,我们模拟实现过vector的迭代器,这里放上代码看看:

namespace knous
 
{
 
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;


        iterator begin()
		{
			return _start;
		}
 
		iterator end()
		{
			reruen _finish;
		}
 
		const_iterator cbegin()
		{
			reruen _start;
		}
 
		const_iterator cend() const
		{
			rerurn _finis;
		}
 
 
 
 
	private:
		iterator _start; // 指向数据块的开始
 
		iterator _finish; // 指向有效数据的尾
 
		iterator _endOfStorage; // 指向存储容量的尾
 
	};
 
}

可以看到vector的迭代器其实就是指针,分别指向vector的头尾两端,因为其底层空间是连续,所以下标可以直接++,但是list就不一样了

template<class T, class Ref,class Ptr >
	struct __list_iteartor
	{
		typedef list_node<T> Node;
		typedef __list_iteartor<T, Ref, Ptr > self;
 
		__list_iteartor(Node* Node)
			:_node(Node)
		{}
 
		Ref operator*()
		{
			return _node->_data;
		}
 
		Ptr operator->()
		{
			//return &(operator*());
			return &_node->_data;
		}
 
		bool operator!=(const self& it)
		{
			return _node != it._node;
		}
		
		self operator++(int)
		{
			_node = _node->_next;
			return _node;
		}
 
		self operator++()
		{
			Node* tmp(*this);
			_node = _node->_next;
			return tmp;
		}
 
		self operator--(int)
		{
			_node = _node->_prev;
			return _node;
		}
 
		self operator--()
		{
			_node = _node->_prev;
			return _node;
		}
 
		Node* _node;
	};

因为list底层空间并不连续,所以我们常规的一些操作无法直接使用,例如++、--,为了解决这种困难,所以将迭代器单纯封了一个类出来,上面就是list迭代器的代码

那反向迭代器应该是什么样子的,以下面这个举例子:

原本应该是1 2 3 4,现在变成了 4 3 2 1

这里借用我之前的一张图:

这张图可以很好的帮我们理解反向迭代器,其rbegin跟end指向的是同一块空间,也就是说,我们对这一块空间明面上是++,实际上是--,知道rbegin到rend,也就是begin的位置,迭代器就走完了全部。

模拟实现

 明白了大致逻辑,接下来就正式开写:

这里我用list来写一个反向迭代器,随后复用到vector里面

    template<class iterator, class Ref, class Ptr >
	struct Reverse_iterator
	{
        iterator _it;
		typedef Reverse_iterator<iterator,Ref, Ptr > self;
	};

反向迭代器,其本质也是一个迭代器,只不过在实现方式上有所不同,这里就直接复用迭代器部分

构造

Reverse_iterator(iterator it)
			:_it(it)
		{}

借用它传进来的指针来初始化这个迭代器对象

解引用

这里要注意的一点是,我们的rbegin和rend跟stl库里面保持一致,它的rbegin对应的是end,而迭代器里面的end其实是头节点


		iterator begin()
		{
			return iterator(_head->_next);
		}

		const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}

那我们实现的时候就要注意,如果此时rbegin是头节点,那我们对头节点解引用,返回的应该是头节点上一个节点解引用

所以写出如下代码:

		Ref operator*()
		{
			return *(--_it);
		}

++

注意反向迭代器的++实际上是正向迭代器的--,这里直接复用即可

		self operator++()
		{
			--it;
			return *this;
		}

--

反向迭代器的--,实际上就是正向迭代器的++,复用

		self operator-()
		{
			++it;
			return *this;
		}

!=

		bool operator!=(const self& it)
		{
			return _it != it._it;
		}

这里还要写一点,就是在list里面加一个反向迭代器的接口:

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

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

		const_reverse_iterator rend() const
		{
			return const_reverse_iterator(begin());
		}

这里的节点跟迭代器反过来即可

看看效果:

对比:

 

 list可以调用这个反向迭代器,vector呢?

vector的复用

		reverse_iterator rbegin()
		{
			return reverse_iterator(_finish);
		}

		reverse_iterator rend()
		{
			return reverse_iterator(_start);
		}

		const_reverse_iterator rcbegin()
		{
			reruen const_reverse_iterator(_finish);
		}

		const_reverse_iterator rcend() const
		{
			rerurn const_reverse_iterator(_start);
		}

同样新增的几个参数,并且将重命名一下模板的名字

		typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;

调用:

对比

 这里放上全部代码:

namespace knous
{

	template<class iterator, class Ref, class Ptr >
	struct Reverse_iterator
	{
		iterator _it;

		typedef Reverse_iterator<iterator, Ref, Ptr > self;

		Reverse_iterator(iterator& it)
			:_it(it)
		{}

		Ref operator*()
		{
			iterator tmp = _it;
			return *(--tmp);
		}

		self operator++(int)
		{
			--_it;
			return *this;
		}

		self operator--(int)
		{
			++_it;
			return *this;
		}


		bool operator!=(const self& it)
		{
			return _it != it._it;
		}
	};
}

注意,要使用这个反向迭代器需要先有正向代码器,同时包上这两个typedef

		typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;

即可正常使用,谢谢观看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值