反向迭代器

反向迭代器

反向迭代器的概念

反向迭代器是一种特殊的迭代器,简单的理解就是他与正向迭代器移动的方向正好相反,即:

  1. 反向迭代器的++ = 正向迭代器的 --
  2. 反向迭代器的 -- = 正向迭代器 的++

在使用STL的时候我们会接触到许多反向迭代器的接口,例如:
在这里插入图片描述
在这里插入图片描述
这些接口返回的类型都是反向迭代器类型,这些接口一般封装在STL容器中。

下面来看一下封装在反向迭代器类中的成员函数:
在这里插入图片描述

这里唯一要注意的就是operator*的指向问题,关于这个问题,我们首先要了解rbegin()rend()的指向
在这里插入图片描述

rend()rbegin()正好与begin()end()的指向相反,但是在operator*()函数上两种迭代器就不一样了

  • 正向迭代器:
    operator*()返回值就是当前迭代器所指向的元素
  • 反向迭代器
    operator*()返回值就是当前迭代器所指向的前一个元素

这样做的原因是为了方便遍历:

int main()
{
    vector<int> s = { 1,2,3,4,5,6,7,8,9 };
    auto it = s.begin();
    while (it != s.end())
    {
        cout << *it << ' ';
        it++;
    }
    cout << endl;
    auto is = s.rbegin();
    while (is != s.rend())
    {
        cout << *is << ' ';
        is++;
    }
}

反向迭代器的实现

反向迭代器实现实际上是一种适配器模式,我们知道迭代器的实现是要知道不同容器底层的实现,从而才能实现各种运算符重载,所以一般封装在容器代码的内部,然而反向迭代器与正向迭代器存在强相连关系,所以反向迭代器可以写成封装正向迭代器的适配接口。


namespace sht
{
	//ref 是数据结构里面数据类型的引用,可以理解为T&
	//Ptr 是数据类型的地址,可以理解为T*

	// 反向迭代器的rbegin =  正向迭代器的 begin
	//反向迭代器的rend =  正向迭代器的 end
	template<class iterator, class Ref,class Ptr> //这里由于不会迭代器萃取,所以把类型也传进来了,实际源码实现只用传第一个参数
	class reverse_iterator
	{
		typedef reverse_iterator<iterator, Ref, Ptr> Self;
	public:
		reverse_iterator(iterator it)
			:_it(it)
		{

		}

		Ref operator*()  //返回迭代器指向的前一个元素
		{
			iterator tmp = _it;   
			return *(--tmp);      //正是因为begin =rend end=rbegin 所以这里解引用时正向迭代器的解引用运算符会对tmp的合法性进行检查
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}
		

		bool operator!=(const Self& t) const
		{
			return _it != t._it;
		}

		bool operator==(const Self& t) const
		{
			return _it == t._it;
		}

	private:
		iterator _it;
	};
}

由于反向迭代器封装了正向迭代器,反向迭代器的构造,拷贝都是调用正向迭代器的构造和拷贝,所以完全可以不知道stl容器的底层实现,只需专注两种迭代器的逻辑关系,这就是反向迭代器的设计巧妙之处。但是这里要求正向迭代器要有完整的构造,拷贝,负值重载函数,不然反向迭代器就无法实现。

在复用的时候只需要引用该头文件即可,这里给出反向迭代器在string模拟实现的代码:string模拟实现

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值