文章目录

  • reverse_iterator认识
  • reverse_iterator 模拟实现
    • reverse_iterator在list内部的使用
    • reverse_iterator在vector内部的使用

reverse_iterator认识

链接:文档

成员类型

成员 定义在reverse_iterator 描述
iterator_type Iterator Iterator的类型
iterator_category iterator_traits::iterator_category 保留类别Iterator
value_type iterator_traits::value_type 保留的值类型Iterator
difference_type iterator_traits::difference_type 保留的差异类型Iterator
pointer iterator_traits::pointer 保留的指针类型Iterator
reference iterator_traits::reference 保留 的引用类型Iterator

迭 代
单相迭代器、双向迭代器类型、随机访问迭代器

功能类型参见下图:

reverse_iterator 模拟实现

链接:reverse_iterator 模拟实现代码
实现的方法
执行的操作:每当 递增时,其基迭代器就会减少,反之亦然。
意思就是复用正向迭代器。
具体代码如下:

#pragma oncenamespace Ding
{template <class Iterator, class Ref, class Ptr>struct __reverse_iterator{Iterator _cur;typedef __reverse_iterator<Iterator, Ref, Ptr> RIterator;__reverse_iterator(Iterator it): _cur(it){}RIterator operator++(){--_cur;return *this;}RIterator operator--(){++_cur;return *this;}Ref operator*(){auto tmp(_cur);//解引用不改变位置--tmp;//反向迭代器开始的位置是正向迭代器结束的位置也就是最后一个元素的下一个位置;所以要--。return *tmp;}Ptr operator->(){//return _cur.operator->();//可以复用正向迭代器的->return &(operator*());}bool operator != (const RIterator& it)const{return _cur != it._cur;}};}

注意:
->和*的重载…也就是迭代器存在的意义是不暴露底层实现细节的情况下提供了统一的方式去访问容器屏蔽底层实现细节,体现封装价值和力量。

reverse_iterator在list内部的使用

如图:

typedef  __reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef  __reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;reverse_iterator rbegin()
{return reverse_iterator(end());//复用
}const_reverse_iterator rbegin() const
{return const_reverse_iterator(end());
}reverse_iterator rend()
{return reverse_iterator(begin());
}const_reverse_iterator rend() const
{return const_reverse_iterator(begin());
}

list整体模拟实现的代码:

namespace Ding
{template <class T>struct list_node{T _date;list_node<T>* _prev;list_node<T>* _next;list_node(const T& x = T()): _date(x), _prev(nullptr), _next(nullptr){}};/*List 的迭代器迭代器有两种实现方式,具体应根据容器底层数据结构实现:1. 原生态指针,比如:vector2. 将原生态指针进行封装,因迭代器使用形式与指针完全相同,因此在自定义的类中必须实现以下方法:1. 指针可以解引用,迭代器的类中必须重载operator * ()2. 指针可以通过->访问其所指空间成员,迭代器类中必须重载oprator->()3. 指针可以++向后移动,迭代器类中必须重载operator++()与operator++(int)至于operator--() / operator--(int)释放需要重载,根据具体的结构来抉择,双向链表可以向前             移动,所以需要重载,如果是forward_list就不需要重载--4. 迭代器需要进行是否相等的比较,因此还需要重载operator == ()与operator != ()*/template <class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> iterator;//find  编译器的检测typedef bidirectional_iterator_tag iterator_category;typedef T value_type;typedef Ptr pointer;typedef Ref reference;typedef ptrdiff_t difference_type;__list_iterator(Node* node = nullptr):_node(node){};// 具有指针类似行为Ref operator*(){return _node->_date;}Ptr operator->(){return &(operator*());//return &(*_node);}bool operator == (const iterator& it)const{return _node == it._node;}bool operator != (const iterator& it)const{return _node != it._node;}iterator& operator++(){_node = _node->_next;return *this;}iterator operator++(int){iterator tmp(*this);_node = _node->_next;return tmp;}iterator& operator--(){_node = _node->_prev;return *this;}iterator operator--(int){iterator tmp(*this);_node = _node->_prev;return tmp;}Node* _node;};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  __reverse_iterator<iterator, T&, T*> reverse_iterator;typedef  __reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;//哨兵位头结点void CreateHead(){_head = new Node;_head->_next = _head;_head->_prev = _head;}list(){CreateHead();}iterator begin(){return iterator(_head->_next);}const_iterator begin() const{return const_iterator(_head->_next);}iterator end(){return iterator(_head);}const_iterator end() const{return const_iterator(_head);}reverse_iterator rbegin(){return reverse_iterator(end());}const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}void push_back(const T& x){/*Node* tail = _head->_prev;Node* newnode = new Node(x);newnode->_prev = tail;newnode->_next = _head;tail->_next = newnode;_head->_prev = newnode;*/insert(end(), x);}void push_front(const T& x){insert(begin(), x);}iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;prev->_next = newnode;return iterator(newnode);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* next = cur->_next;Node* prev = cur->_prev;prev->_next = next;next->_prev = prev;delete cur;return iterator(next);}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}~list(){clear();delete _head;_head = nullptr;}template <class Iterator>list(Iterator first, Iterator last){CreateHead();while (first != last){push_back(*first);++first;}}void swap(list<T>& x){std::swap(x._head, _head);}list(const list<T>& l){CreateHead();// 用l中的元素构造临时的temp,然后与当前对象交换list<T> temp(l.begin(), l.end());swap(temp);}list<T>& operator=(list<T> l){swap(l);return *this;}private:Node* _head;};

结果展示:

reverse_iterator在vector内部的使用

如图:

vector同样保持对称和镜像的“特点”

完整模拟代码:

#pragma once
#define _CRT_SECURE_NO_WARNINGS#include<iostream>
#include<assert.h>
#include<string.h>
#include<string>
#include<vector>#include"reverse_iterator.h"using namespace std;namespace Ding
{template <class T>class vector{public:// Vector的迭代器是一个原生指针typedef T* iterator;typedef const T* const_iterator;typedef  __reverse_iterator<iterator, T&, T*> reverse_iterator;typedef  __reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}reverse_iterator rbegin(){return reverse_iterator(end());}const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}//vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}vector(int n, const T& value = T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){resize(n, value);}vector(size_t n, const T& value = T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){resize(n, value);}template<class InputIterator>vector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){while (first != last){push_back(*first);++first;}}vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(v.capacity());//一个一个数据的尾插。for (auto e : v){push_back(e);}}vector<T>& operator= (vector<T> v){swap(v);return *this;}~vector(){delete[] _start;_start = _finish = _end_of_storage = nullptr;}//size_t size() const{return _finish - _start;}size_t capacity() const{return _end_of_storage - _start;}bool empty() const{return _start == _finish;}void reserve(size_t n){if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sz * sizeof(T)); //内部浅拷贝for (size_t i = 0; i < sz; ++i)tmp[i] = _start[i];//释放旧空间delete[] _start;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}void resize(size_t n, const T& value = T()){if (n > size()){// 2.空间不够则增容if (n > capacity())reserve(n);//插入size_t sz = size();for (size_t i = 0; i < n - sz; ++i){*_finish = value;++_finish;}}else{//缩小_finish = _start + n;}}//T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos)const{assert(pos < size());return _start[pos];}T& front(){return *_start;}const T& front()const{return *_start;}T& back(){return *(_finish - 1);}const T& back()const{return *(_finish - 1);}// void push_back(const T& x){//if (_finish == _end_of_storage)//{//    //扩容//  size_t cap = capacity() == 0 ? 4 : capacity() * 2;// rserve(cap);//}//*_finish = x;//++_finish;insert(end(), x);  //复用}void pop_back(){assert(_finish > _start);//erase(end() - 1); 复用erase--_finish;}void swap(vector<T>& v){::swap(_start, v._start);::swap(_finish, v._finish);::swap(_end_of_storage, v._end_of_storage);}iterator insert(iterator pos, const T& x){assert(pos >= _start);assert(pos <= _finish);if (_finish == _end_of_storage){//扩容size_t len = pos - _start;size_t cap = capacity() == 0 ? 4 : capacity() * 2;//pos地址要改变reserve(cap);pos = _start + len;}//挪动数据T* end = _finish;while (end > pos){*end = *(end - 1);--end;}//pos位置放数据//*end = x;*pos = x;++_finish;return pos;}iterator erase(iterator pos){assert(pos >= _start);assert(pos < _finish);//删除数据iterator begin = pos + 1;while (begin < _finish){*(begin - 1) = *begin;++begin;}--_finish;return pos;}private:iterator _start;  // 指向数据块的开始iterator _finish; // 指向有效数据的尾iterator _end_of_storage; // 指向存储容量的尾};
}

结果展示:

反向迭代器---迭代器适配器相关推荐

  1. python迭代器-迭代器取值-for循环-生成器-yield-生成器表达式-常用内置方法-面向过程编程-05...

    迭代器 迭代器 迭代: # 更新换代(其实也是重复)的过程,每一次的迭代都必须基于上一次的结果(上一次与这一次之间必须是有关系的) 迭代器: # 迭代取值的工具 为什么用迭代器: # 迭代器提供了一种 ...

  2. 【C++】反向迭代器--迭代器适配器

    前言 大家好呀~欢迎进入我的这篇学习笔记~ 我的上一篇C++文章传送点在这里哦:[C++]stack.queue.priority_queue的模拟实现_柒海啦的博客-CSDN博客 我们知道,在C++ ...

  3. 2022-1-21 迭代器的适配器

    adapter 统一的做法是将原来的对象记下来,再包装上新的一层接口. 反向迭代器就是对于原来的迭代器取相反的操作. advance () 可以将链表的迭代器移动指定的步数,毕竟链表的迭代器没有 + ...

  4. Lua学习笔记08:无状态的迭代器(迭代器与泛型for-02)

    无状态迭代器:一种自身不保存任何状态的迭代器.因此,我们可以在多个循环中使用同一个无状态的迭代器,避免创建新的closure 开销.(在一个迭代器方法中,其return直接返回一个或多个值,而不是在r ...

  5. 【c++】:反向迭代器适配器:每天学一点点优秀的思想

    文章目录 前言 一.list的反向迭代器 vector的反向迭代器 总结 前言 反向迭代器的适配只用于双向迭代器,对于单链表实现的单向迭代器是不能通过适配构造一个反向迭代器的,为什么要说反向迭代器适配 ...

  6. C++迭代器之'反向迭代器'

    反向迭代器(Reverse Iterator)是普通迭代器的适配器,通过重新定义自增和自减操作,以达到按反序遍历元素的目的.如果在标准算法库中用反向迭代器来代替普通的迭代器,那么运行结果与正常情况下相 ...

  7. 【C++】反向迭代器

    文章目录 一.什么是反向迭代器 二.STL 源码中反向迭代器的实现 三.reverse_iterator 的模拟实现 四.vector 和 list 反向迭代器的实现 一.什么是反向迭代器 C++ 中 ...

  8. STL-reverse_iterator 反向迭代器

    回顾 对于STL中的容器,迭代器(iterator)是很重要的部分,同时迭代器也是STL六大组件之一,在之前我们实现vector和list中,我们已经对于迭代器有了初步的认识,为什么设计迭代器? 就是 ...

  9. 顺序容器(vector、list、string、deque、forward_list)及迭代器、容器适配器

    文章目录 概述 所有容器都支持的操作 迭代器 迭代器支持的操作 迭代器支持的算术运算 容器类型 size_type iterator 和 const_iterator 容器定义和初始化 拷贝初始化 顺 ...

最新文章

  1. 增加ESXI中虚拟机CENTOS系统分区容量
  2. 06一键直达:一键整理、秒搜、秒开任何文件、软件、网址
  3. VTK:PolyData之SelectVisiblePoints
  4. getParameter
  5. 六、Python之三元表达式、列表推导式、生成器表达式
  6. 邓迎春绘画201702作品5
  7. 怎样让你的Linux使用起来更像Windows
  8. 百度语音识别技术突破 巨头崛起
  9. linux mysql优化_Linux上跑MySQL优化技巧
  10. matlab各向异性高斯核方向导数滤波器,基于各向异性高斯方向导数滤波器提取图像粗边缘的方法...
  11. scl语言用plc脉冲做定时器_scl语言用plc脉冲做定时器_西门子PLC SCL语言开发学习笔记(二)...
  12. eclipse修改自定义皮肤
  13. 移动硬盘插上电脑卡住_插入移动硬盘死机故障分析及解决方案(图文详解)
  14. 为什么说Python现在是风口上的猪?
  15. html文字往右边偏移怎么做,div向右偏移设置 css让div靠右移必定距离
  16. 【亲测有效!!!】解决git did not exit cleanly (exit code 1) 错误
  17. openwrt 15.05 branch (Chaos Calmer)编译出的固件bootargs被覆盖
  18. C语言实现操作系统的进程调度算法--RR算法
  19. 2017年8月22日 星期二
  20. JAVA解决OPTIONS请求问题:跨域时ajax发送两次请求,其中options预请求参数为null及其解决方案

热门文章

  1. 数据分析:销售数据分析如何做?这篇干货收藏备用!
  2. memcpy越界引起的segment fault
  3. Hadoop学习——Hadoop概述
  4. 现货黄金入门:初识心理
  5. firefox手动设置火狐浏览器的默认主页
  6. vue3.x 使用jsplumb进行拖拽连线
  7. 618将至,各产品营销活动通用文案合集分享,有需要的进
  8. 圣诞节儿童什么礼物好呢?精选实用型的圣诞护眼小台灯
  9. Linux搭建Web网站
  10. 中国将取代德国成世界第三大经济体