目录
前言
前面我们学习的C++中适配器模式的一个例子:栈和队列的模拟实现,C++中的适配器模式本质上是一种代码复用的手段,其可以实现相同功能代码的复用,而不会写出一些重复的代码,从而造成代码的冗余。C++中另一个适配器模式的经典设计就是反向迭代器的封装,其通过适配正向迭代器的功能,从而实现了反向迭代器的功能,本篇文章将重点讲解C++中反向迭代器的适配模式,并以list和vector的反向迭代器为例。
一、反向迭代器的实现
1. 底层
反向迭代器的底层是适配了正向迭代器,所以反向迭代器的成员变量是正向迭代器。其形式如下:
template<class Iterator,class Ref,class Ptr>
struct Reverse_iterator
{
Iterator _it;
}
2. 成员函数
1. 构造函数
反向迭代器中只有一个成员变量:正向迭代器,所以我们需要实现一个带参的构造函数将正向迭代器作为参数来对反向迭代器的成员进行初始化。
// 构造函数
Reverse_iterator(const Iterator& it)
:_it(it)
{
}
2. operator*()
在正向迭代器中,对正向迭代器进行解引用访问的是这个迭代器指向的结点中的数据,但是反向迭代器和正向迭代器有所不同,反向迭代器调用operator*()之后访问的是当前反向迭代器指向的结点的前一个结点的数据。
// *
Ref operator*()
{
Iterator tmp(_it);
return *(--tmp);
}
3. operator->()
operator->()的作用是求当前迭代器指向的结点中的数据的地址,所以可以通过调用operator*()之后再取地址,也可以直接返回上一个结点的数据的地址。
// ->
Ptr operator->()
{
return &(operator*());
}
4. 前置++
正向迭代器中的++是朝正方向走,单向迭代器是朝着反方向走,所以可以通过正向迭代器中的–进行实现
// ++
Self& operator++()
{
--_it;
return *this;
}
5. 后置++
当反向迭代器的前置++实现了之后,后置++可以通过调用前置++的功能完成
// ++
Self& operator++()
{
--_it;
return *this;
}
6. 前置–
正向迭代器中的–是朝反方向走,单向迭代器是朝着正方向走,所以可以通过正向迭代器中的++进行实现
// --
Self& operator--()
{
++_it;
return *this;
}
7. 后置–
当反向迭代器的前置–实现了之后,后置–可以通过调用前置–的功能完成
Self operator--(int)
{
Self tmp(*this);
--(*this);
return tmp;
}
8. operator!=()
反向迭代器的!=可以通过正向迭代器的!=进行判断
// !=
bool operator