前言
在之前我们学习了正向迭代器,const迭代器,今天我们来学习一下反向迭代器,我们这次需要用到之前所学的适配器的知识。不是单纯的是实现反向迭代器。
一、正向迭代器的回顾
我们在之前实现list的模拟实现时,学习到了正向迭代器。
我们回顾一下是怎末实现的??
我们的list是一个带头双向循环链表。我们需要自己设计一个迭代器使用,因为++, - -并不是普通的++,- -。迭代器的本质就是指针,由于指针属于内置类型,我们实现运算符重载需要使用自定义类型,所以我们对这个指针进行封装。
++就是找到下一个节点,- -就是前一个节点。我们实现了一系列功能。
为了避免代码重复,我们又根据正向迭代器,在原有正向迭代器的基础上,稍微修改,设计出了const迭代器。
template
class list
{
public:
typedef ListNode Node;
typedef __iterator_list<T, T&, T*> iterator;
typedef __iterator_list<T, const T&, const T*> const_iterator;
}
二、反向迭代器
我们实现一个反向迭代器是很简单的,不就是在原有迭代器的基础上修修补补就可以,本来指向下一个的节点,现在指向前一个。
但是大佬们的设计并不是这样,他们是这站在巨人的肩膀上看问题。
他们要实现的是设计一个能适合所有容器的迭代器。适合链表,数,string等等。
我们仔细发现一下,反向迭代器的++不就是正向迭代器的- - 吗!反向迭代器的- - 不就是正向迭代器的++ 吗!
反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。这不就是我们所学到的适配吗
给我一个list的正向迭代器,我给你适配一个list的反向迭代器。
给我一个树的正向迭代器,我给你适配一个树的反向迭代器。
简单的接口我们就不在这里进行阐述了,我们看一下这个解引用操作
我们看一下库里边的rbegin(),rend()的位置。这里库里边是为了对称设计成这样的。
我们再进行解引用时候就需要先减减,再进行解引用
template<class Iterator , class Ref , class Def >
struct Reverse_Lterator
{
public:
typedef Reverse_Lterator<Iterator, Ref, Def> self;
Reverse_Lterator(Iterator it)
:_it(it)
{ }
//后置
self operator++(int)
{
Iterator tmp(_it);//先拷贝一份
_it--;
return tmp;
}
self& operator++()
{
--_it;
return *this;
}
self operator--(int)
{
Iterator tmp(_it);
_it++;
return tmp;
}
self& operator--()
{
++_it;
return *this;
}
bool operator !=(const self& tmp)
{
return _it != tmp._it;
}
void operator =(const self& tmp)
{
_it = tmp._it;
}
Ref operator*()
{
Iterator tmp(_it);
--tmp;
return *tmp;
}
private:
Iterator _it;
};
我们看一下这个地方
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
反向迭代器的实现是用正向迭代器适配出来的。
总结
以上就是今天要讲的内容,本文仅仅详细介绍了C++反向迭代器模拟实现。希望对大家的学习有所帮助,仅供参考 如有错误请大佬指点我会尽快去改正 欢迎大家来评论~~ 😘 😘 😘