【C++】反向迭代器模拟实现
👀樊梓慕:个人主页
🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》
🌝每一个不曾起舞的日子,都是对生命的辜负
目录
前言
1.利用适配器的思想
2.有关operator*注意
3.利用vector来举例说明
前言
之前我们已经模拟实现过vector、list等容器,但其中我们仅实现了普通迭代器与const迭代器,今天我们就来学习下反向迭代器的实现。
欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。
=========================================================================
GITEE相关代码:🌟fanfei_c的仓库🌟
=========================================================================
1.利用适配器的思想
我们知道stack、queue等不称为容器,而被称作『适配器 』,因为他们的底层是容器deque,即只需要利用deque这个结构来满足stack、queue的特性,此时stack和queue就是一种适配器。
那反向迭代器是不是就是普通迭代器的一种适配呢?
反向迭代器需不需要我们从零开始写呢?还是和适配器一样,利用普通迭代器的结构满足反向迭代器的特性即可?这样是不是比较方便?
- rbegin()相当于end()
- rend()相当于begin()
- 反向迭代器++相当于正向迭代器--
- 其他操作* != ->和正向迭代器相同
那么我们再拔高一层:
每一种容器或适配器都要实现自己的反向迭代器,如果是这样的话代码会不会太冗余了,因为他们的反向迭代器的逻辑都是相同的。
所以我们可以利用模板参数、泛型来通过传递不同的模板参数来让编译器自己推演出对应容器或适配器的反向迭代器即可。
反向迭代器类:
template<class Iterator, class Ref, class Ptr>
struct ReverseIterator
{typedef ReverseIterator<Iterator, Ref, Ptr> Self;Iterator cur;ReverseIterator(Iterator it):cur(it){}Self& operator++()//前置++{--cur;return *this;}Self operator++(int)//后置++{Iterator tmp = cur;--cur;return tmp;}Self& operator--()//前置--{++cur;return *this;}Self operator--(int)//后置--{Iterator tmp = cur;++cur;return tmp;}Ref operator*()//解引用{Iterator tmp = cur;--tmp;return *tmp;}Ptr operator->(){return &(operator*());}bool operator!=(const Self& s){return cur != s.cur;}bool operator==(const Self& s){return cur == s.cur;}};
2.有关operator*注意
为了其对称性,使得rbegin()等价于end(),rend()等价于begin()。
- 但由于end是指向最后一个元素的『 下一个位置』,而rbegin由end适配得到,所以反向迭代器中的operator*()不是返回迭代器的当前位置的数据,而是返回迭代器当前位置的『 前一个位置』的数据。
即如果我们需要返回当前位置的数据,可以将rbegin()由--end(),rend()由--begin()进行适配即可。
3.利用vector来举例说明
template<class T>
class vector
{
public:typedef T* iterator;typedef const T* const_iterator;typedef ReverseIterator<iterator, T&, T*> reverse_iterator;typedef ReverseIterator<const_iterator, T&, T*> const_reverse_iterator;reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}vector(){}vector(const vector<T>& v);template <class InputIterator>vector(InputIterator first, InputIterator last);vector(size_t n, const T& val = T());vector(int n, const T& val = T());vector<T>& operator= (vector<T> v);~vector();size_t size() const;size_t capacity() const;void reserve(size_t n);void resize(size_t n, const T& val = T());T& operator[](size_t pos);const T& operator[](size_t pos)const;void push_back(const T& x);void pop_back();void swap(vector<T>& v);iterator insert(iterator pos, const T& x);iterator erase(iterator pos);
private:iterator _start = nullptr; // 指向数据块的开始iterator _finish = nullptr; // 指向有效数据的尾iterator _endOfStorage = nullptr; // 指向存储容量的尾
};
如图:根据模板参数int和reverse_iterator可以推演出该反向迭代器的各个模板参数类型,在反向迭代器类中写一个构造函数,该构造函数就是利用的适配器思想,将普通迭代器iterator传递给反向迭代器ReverseIterator,然后利用普通迭代器iterator的++或--方法实现反向迭代器。
同样的类比到List中:
=========================================================================
如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容
🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎
🌟~ 点赞收藏+关注 ~🌟
=========================================================================