当前位置: 首页 > news >正文

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的函数

http://www.lryc.cn/news/609098.html

相关文章:

  • Java基本技术讲解
  • 深入解析C++函数重载:从原理到实践
  • 【1】WPF界面开发入门—— 图书馆程序:登录界面设计
  • K8S部署ELK(五):集成Kibana实现日志可视化
  • B+树索引结构原理解析与最佳实践
  • 创建型设计模式:对象诞生的艺术与智慧
  • 设计模式学习[17]---组合模式
  • 控制建模matlab练习06:比例积分控制-②PI控制器
  • 【stm32】按键控制LED以及光敏传感器控制蜂鸣器
  • STM32-驱动OLED显示屏使用SPI(软件模拟时序)实现
  • Spring Boot 的事务注解 @Transactional 失效的几种情况
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-55,(知识点:STM32,外设及其特点)
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第四天(DOM编程和AJAX异步交互)
  • 08【C++ 初阶】类和对象(下篇) --- 类知识的额外补充
  • MySQL 事务原理 + ACID笔记
  • 计算机网络(TCP篇)
  • Python3 中使用zipfile进行文件(夹)的压缩、解压缩
  • Qt-vs加载exe图标
  • 【机器人】VLN-R1 微调 | 增强训练 | 连续导航
  • 江协科技STM32 14-1 WDG看门狗
  • 一键安装RabbitMQ脚本
  • 数据结构(概念及链表)
  • 【数据分享】各省粮食外贸依存度、粮食波动率等粮食相关数据合集(2011-2022)(获取方式看文末)
  • 达梦数据库备份与还原终极指南:从基础到增量策略实战
  • 【2025/08/03】GitHub 今日热门项目
  • Spring 核心之 Bean 管理:配置、作用域与生命周期详解
  • 计算机核心概念辨析与解析
  • LeetCode 2122.还原原数组
  • OpenWrt | 如何在 ucode 脚本中打印日志
  • C语言的基本结构