反向迭代器就是反向遍历的迭代器,他和正向迭代器有和很多功能是重复的,因此我们用适配器的形式来写反向迭代器。在这里,我们需要注意在库里rbegin()和rend()的指向位置,如图:
这里当我们使用*访问节点时,实际是访问反向迭代器指向的上一个节点,如:*rbegin(),访问的是rbegin()指向的上一个节点,也就是4。C++库里采用这种方式是为了形成一个对称(其他方式也能实现),在代码中我们也使用该方法进行实现。
#pragma once
namespace bit
{
// 适配器 -- 复用
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;
}
self& operator ++()
{
--_it;
return *this;
}
self operator ++(int)
{
Iterator tmp = _it;
_it--;
return tmp;
}
self operator --(int)
{
Iterator tmp = _it;
_it++;
return tmp;
}
self& operator --()
{
++_it;
return *this;
}
Ref operator *()
{
Iterator tmp = _it;
return *(--tmp);
}
Ptr operator ->()
{
Iterator tmp = _it;
return &(*--tmp);
}
bool operator != ( const self& m)
{
return _it != m._it;
}
};
}
这里我们主要用了正向迭代器的功能,重载了相应的运算符,这样反向迭代器的外部就实现完成了。在我们自己实现的STL类中我们还要加入下列代码,才能使用。以List为例子(list的简易实现可以看前几期的博客),加入下列代码:
typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef Reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
reverse_iterator rbegin()
{
return end();
}
reverse_iterator rend()
{
return begin();
}
reverse_iterator rbegin()const
{
return end();
}
reverse_iterator rend()const
{
return begin();
}
这样list里的反向迭代器就完成了,如果想实现其他STL容器的方向迭代器,只要加入上面这一段代码到相应STL容器的代码实现就行,这样实现了对Reverse_iterator类的代码重复使用,我们来运行试试
#include "List.h"
using namespace bite;
int main()
{
list<int> l(5, 1);
l.push_back(2);
list<int>::reverse_iterator it = l.rbegin();
while (it != l.rend())
{
cout << *it << endl;
it++;
}
}
运行结果如下:
讲解完毕,如有错误和疑问可以评论区提出。