C++ : 反向迭代器的模拟实现
一、reverse_iterator.h
#pragma once
namespace txf
{ //外界传什么类型的iteator,它就用什么iterator 初始化 , list用_list_iterator<T,T&,,T*> ,vector<T> 用T*template<class Iterator,class Ref,class Ptr>//在这个反向迭代器中涉及到返回引用和地址的const/普通对象,struct ReverseIterator //所以用模版Ref 和 Ptr{typedef ReverseIterator<Iterator, Ref, Ptr> self;Iterator _it;//反向迭代器除去接口,就只是一个正向迭代器,反向迭代器的接口建立在正向迭代器的接口之上,所以需要一个正向迭代器作为ta的成员变量ReverseIterator(Iterator it)//外界传哪里的地址,它就在那个地址上,然后ta可以有一系列操作:_it(it){}Ref operator *()//不动当前数据 {Iterator tmp(_it);return *(--tmp);}Ptr oprtator->(){return &(operator*());}self& operator++(){--_it;return *this;}self& operator++(int){self tmp(_it);--_it;return tmp;}self& operator--(int){self tmp(_it);++_it;return tmp;}self& operator--(){++_it;return *this;}bool operator!=(const self& s)const{return _it != s._it;}bool operator==(const self& s)const{return _it == s._it;}};
}
二、反向迭代器的介绍
template<class Iterator,class Ref,class Ptr>//在这个反向迭代器中涉及到返回引用和地址的const/普通对象,
- 反向迭代器是一个模板类,外界传什么类型的iteator,它就要适配出该类型的反向迭代器,所以,ta 也是一个适配器,即适配正向迭代器达到反向遍历的效果,通过对正向迭代器实例化出的对象的接口进行封装进而达到反向遍历的效果 ,当正向迭代器的- -时,反向迭代器++,正向迭代器的++,反向迭代器的- -
- 在这个反向迭代器中涉及到返回引用和地址的const/普通对象,所以我们传模版,Ref - T&/const T&, Ptr - T*/const T*,更方便
struct ReverseIterator
- strcut的默认访问方式是public,方便直接访问其成员
typedef ReverseIterator<Iterator, Ref, Ptr> self;
- 为了便利 ,将迭代器的类型ReverseIterator<Iterator, Ref, Ptr>使用typedef重命名为self
Iterator _it;
- 反向迭代器除去接口,就只是一个正向迭代器,反向迭代器的接口建立在正向迭代器的接口之上,所以需要一个正向迭代器作为ta的成员变量
ReverseIterator(Iterator it):_it(it){}
- 外界传哪里的地址,它就指向那个地址上,然后ta可以一系列操作:++、--.....
Ref operator *(){Iterator tmp(_it);return *(--tmp);}
- 不动当前数据
- begin() : 头结点的地址
- end() : 尾节点的地址的下一个位置
- rbegin() : 尾节点的地址
- rend() : 头结点的地址的下一个位置
原先的指向 :
为了让正向迭代器与反向迭代器相对应 :
实现上图的效果,我们在用反向迭代器时,用begin 初始化 rend(把begin 的地址拷贝给rend) ,用end 初始化rbegin,因此,反向迭代器的rend 和 rbegin 对应原先的位置是相当于往后走了一步,我们在用时要把它还原回来,所以要 "--tmp" , 让正向迭代器与反向迭代器相对应只是想对称,让它的底层是图二这样的, 但在使用的时候要让它是图一这样的
Ptr oprtator->()
{return &(operator*());
}
- 当容器内部存储的是结构体类型的时候,可以使用->取出成员的地址,即结构体地址也就是该位置的迭代器进行返回
- 模板参数Ptr,这里对于返回值,直接采用Ptr即可,对应const对象和普通对象都会在容器的实现中传入对应的类型
self& operator++(){--_it;return *this;}
- 这里实际上是调用的正向迭代器_it的- -完成的
- 返回this指针指向的对象,由于*this的对象存在,不会销毁,这里返回其引用
self& operator--(){++_it;return *this;}
- 这里实际上是调用的正向迭代器_it++完成的
- 返回this指针指向的对象,由于*this的对象存在,不会销毁,这里返回其引用
bool operator!=(const self& s)const{return _it != s._it;}
- 进行两个反向迭代器的比较,采用引用传参,减少拷贝
- 反向迭代器本质是对正向迭代器的封装,进行反向迭代器的比较,也可以调用正向迭代器的比较
bool operator==(const self& s)const{return _it == s._it;}
- 进行两个反向迭代器的比较,采用引用传参,减少拷贝
- 反向迭代器本质是对正向迭代器的封装,进行反向迭代器的比较,也可以调用正向迭代器的比较
总结
本文,小编我只是简单的介绍了reverse_iterator 的实现和解释,我们写的反向迭代器是泛型的,支持正向迭代器的容器都能使用,在 vector 或 list 中 都会把ReverseIterator<iterator, T&, T*> tpedef 成reverse_iterator/ReverseIterator<const_iterator ,const T&,const T*> typedef 成const_reverse_iterator ,在类中实现reverse_iterator的函数