冰冰学习笔记:反向迭代器的模拟

欢迎各位大佬光临本文章!!!

 

还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正。

本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位大佬、帅哥、美女点点支持,您的每一分关心都是我坚持的动力。

我的博客地址:bingbing~bang的博客_CSDN博客https://blog.csdn.net/bingbing_bang?type=blog

我的gitee:冰冰棒 (bingbingsupercool) - Gitee.comhttps://gitee.com/bingbingsurercool


系列文章推荐

冰冰学习笔记:《vector的简单模拟》

冰冰学习笔记:《list的简单模拟》


目录

系列文章推荐

前言

1.反向迭代器的使用介绍

2.反向迭代器的模拟实现


前言

        反向迭代器是C++中容器内常见的一种迭代器模式,它与正常的迭代器截然相反,rbegin()指向的是容器末尾位置,rend()指向的则是容器开始位置,并且rbegin的++操作并不是向后移动,而是向前移动,逐步靠近rend()。因此,使用反向迭代器遍历得到的是逆置后的容器结果。

1.反向迭代器的使用介绍

        反向迭代器并不是每个容器都具备,有些容器本身就不具备迭代器的操作,例如栈和队列,使用迭代器会改变其容器本身属性。有些容器则只支持正向迭代器,不支持反向迭代器,例如<forward_list>,<unordered_map>,<unordered_set>。最典型的例子就是单链表,因为单链表只有一个next指针,不具备指向前面元素的指针,更不可能具备反向迭代器。

        反向迭代器的使用与正向迭代器没有什么区别,就是反着来访问容器内容。

        拿链表来举例,按照我们常规的理解,rbegin指向的应该是链表最后一个位置的元素,这样解引用才能拿到最后一个数据,rend指向的则是原来end指向的位置,也就是头节点。可真的是这样吗?

        迭代器是具备类型分类的,迭代器分为单向迭代器,双向迭代器,随机迭代器。迭代器的分类可以帮助我们在使用算法函数时能够正确的传递参数。

 

2.反向迭代器的模拟实现

        对于反向迭代器的实现,我们最先想到的就是重新封装一个类,然后重载里面的++,--操作符,使其向相反的位置移动。但是C++的大佬们并没有使用如此庸俗的手法。

        C++的大佬在实现的时候想的是尽可能多的复用,vector需要实现反向迭代器,list也需要实现反向迭代器,那我们能不能实现通用的一种方式,代码放在vector中能正常使用,放在list,deque中也能使用呢?

        因此,基于这种方式,大佬们将反向迭代器实现成了一种适配器模式,使用原先容器的正向迭代器来实现反向迭代器。

        每个反向迭代器使用原有容器的正向迭代器构建 ,并将运算符进行重载,返回对应的反向迭代器。最值得关注的是解引用操作符的重载,并不是将指向元素的迭代器直接进行访问操作,而是访问前一个位置的元素!

         这是什么原因呢?原因在于,大佬实现的反向迭代器并不是按照我们想的那样rbegin指向的最后一个位置,rend指向的头节点,而是rbegin就是使用end构建,二者指向同一个位置,rend使用begin构建,二者指向同一个位置。这样我们在进行解引用的时候就需要向前移动然后在访问,才能得到正确位置的元素。

        剩下的实现就是运算符的重载,对++,--进行封装。反向迭代器的++操作需要向前移动,因此我们内部将正向迭代器向前移动,然后返回。--操作则同理进行正向迭代器的++操作。

namespace lb
{
	template<class Iterator,class Ref,class Ptr>
	struct __reverse__iterator
	{
		Iterator _cur;//反向迭代器用正向迭代器构建
		typedef __reverse__iterator<Iterator, Ref, Ptr> RIterator;

		__reverse__iterator(Iterator it)//构造
			:_cur(it)
		{}
		RIterator operator++()
		{
			--_cur;
			return *this;
		}
		RIterator operator++(int)
		{
			auto tmp = _cur;
			--_cur;
			return tmp;
		}

		RIterator operator--()
		{
			++_cur;
			return *this;
		}
		RIterator operator--(int)
		{
			auto tmp = _cur;
			++_cur;
			return tmp;
			//return _cur++;
		}
		Ref operator*()
		{
			auto tmp = _cur;
			return *(--tmp);
		}
		Ptr operator->()
		{
			return &(operator*());
		}
		bool operator !=(const RIterator& it)
		{
			return _cur != it._cur;
		}
		bool operator ==(const RIterator& it)
		{
			return _cur == it._cur;
		}
	};
}

        对于list内部,我们就可以直接使用begin,end进行反向迭代器的构建。

typedef __reverse__iterator<iterator, T&, T*> reverse_iterator;
typedef __reverse__iterator<const_iterator, const T&, const T*> const_reverse_iterator;
    reverse_iterator rbegin()
	{
		return reverse_iterator(end());
	}
	reverse_iterator rend()
	{
		return reverse_iterator(begin());
	}
    const_reverse_iterator crbegin()const
	{
		return const_reverse_iterator(cend());
	}
	const_reverse_iterator crend()const
	{
		return const_reverse_iterator(cbegin());
	}

        这样我们实现的反向迭代器无论是deque还是list,vector都可以直接使用对应的正向迭代器进行构建。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bingbing~bang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值