C++ 反向迭代器模拟实现
前言
之前我们已经模拟实现过vector、list等容器,但其中我们仅实现了普通迭代器与const迭代器,今天我们就来学习下反向迭代器的实现。
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中:
到此这篇关于C++ 反向迭代器模拟实现的文章就介绍到这了,更多相关C++ 反向迭代器 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论