前言:
上一章我们介绍了适配器,也提了一下迭代器适配器,今天我们就从反向迭代器把迭代器适配器给解释一下。
既然 都叫迭代器容器了 就说名只要接口合适他可以封装实现各种容器需求包括vector list 。
目录
1.反向迭代器设计
1.1反向迭代器思想
1.2多参数模板
2.vecor反向迭代器
3.list反向迭代器
1.反向迭代器设计
反向迭代器 reverse_iterator
可以用来反向遍历容器,在某些场景下很实用
1.1反向迭代器思想
因为数组比较简单,我们就从数组引出反向的思想。
注:库中的反向迭代器在设计时,为了最求极致的对称,rbegin()
指向最后一个有效元素的下一个位置,rend()
指向第一个有效元素(位置是与正向迭代器相反的)
通过图示知道,反向迭代器的++就是正向迭代器的--。反向迭代器的--就是正向迭代器的++,因此反向迭代器的实现可以借助正向迭代器,即:反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。
1.2多参数模板
在模拟实现list迭代器时候,我们在const对象对普通对象代码的复用的 过程中,引入了多参数模板,不同参数实现不同功能,反向迭代器的实现同样适用。有两点需要注意:
- 重载operator*()返回的是目标对象的引用,又因为库里追求极致对称,所以我们应该先执行--操作后返回对象的引用。
- 具体返回的对象是否需要const修饰,取决于我们使用的模板参数。
#pragma once
namespace cmx
{
template <class iterator, class Ref, class Ptr>
struct Reverselterator
{
typedef Reverselterator<iterator, Ref, Ptr> self;
iterator _it;
Reverselterator(iterator it)
:_it(it)
{}
Ref operator *()
{
iterator tmp = _it;
return *(--tmp);
}
Ptr operator ->()
{
return &(operator*());
}
self& operator++()
{
-- _it;
return *this;
}
self& operator--()
{
++ _it;
return *this;
}
bool operator !=(const self& s) const
{
return _it != s._it;
}
};
}
完成头文件的编写之后,我们就可以把他运用于所有可以用迭代器访问的容器 比如 vector list,只需要修改模版参数中正向迭代器的代码就可以适配出属于自己的反向迭代器。
2.vecor反向迭代器
只需要引用 反向迭代器的头文件 ReverseIterator.h 就可以使用,具体代码如下:
#include<assert.h>
#include"ReverseIterator.h"
namespace cmx
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
typedef Reverselterator<iterator, T&, T*> reverse_iterator;
typedef Reverselterator<const_iterator, const T&, const T*> const_reverse_iterator;
reverse_iterator rebegin()
{
//this调用的end()函数
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
3.list反向迭代器
代码如下:
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef Reverselterator<iterator, T&, T*> reverse_iterator;
typedef Reverselterator<const_iterator, const T&, const T*> const_reverse_iterator;