【C++】-------反向迭代器的模拟实现(补充)

目录

前言

一、反向迭代器接口(用户层)

二、模拟实现

三、以vector模拟实现为例

四、总结


前言

在vector和list的接口中我们实际上有说明过反向迭代器的用法,这里就有个问题,并不是只有这两个容器存在反向迭代器的。那么对于他们底层的实现我们是不是每个容器都写一个反向迭代器?

        其实不是的,实际上不管你是什么容器,每个容器的反向迭代器实现的逻辑都大差不差,每一个容器都实现一段几乎相同的代码,多少有点费时费力,所以在STL库里就实现了一个适合所有具有迭代器的容器的反向迭代器!也就是迭代器适配器(和stack、queue一样的概念),你传入什么容器的正向迭代器,编译器就会适配出什么样的反向迭代器,本质是对正向迭代器的一种封装!!!!

一、反向迭代器接口(用户层)

这里在复习一下两个接口:

rbegin()+rend()

rbegin():返回最后一个元素的反向迭代器,即正向迭代器end的前一个位置。

rend():返回第一个元素之前理论元素的反向迭代器,即正向迭代器begin的前一个位置。

从上面的叙述中不难猜测出:对反向迭代器的++,实际上就是对正向迭代器的--!!

二、模拟实现

有了前面的铺垫这里直接上代码!!注意:这里的模板参数在和list的迭代器类是一样的

namespace Re
{// 适配器 -- 复用template<class Iterator, class Ref, class Ptr>class Reverse_iterator{public:typedef Reverse_iterator<Iterator, Ref, Ptr> self;Reverse_iterator(Iterator it):_it(it){}//*itRef operator*(){Iterator tmp = _it;return *(--tmp);}//it->Ptr operator->(){//复用解引用return &(operator*());}//++itself& operator++(){--_it;//实际上这里调用正向迭代器,即:--endreturn *this;}//--itself& operator--(){++_it;return *this;}//it++ ,后置,先返回+之前的结果,所以要返回临时变量,不能引用接收   self operator++(int){Iterator tmp=_it;--_it;return tmp;}self operator--(int){Iterator tmp=_it;++_it;return tmp;}bool operator!=(const self& s){return _it != s._it;}bool operator==(const self& s){return _it == s._it;}private:Iterator _it;};
}

值得一提的是:它的解引用操作实际上是对前一个位置进行解引用,而不是对当前位置进行解引用!!为啥呢?其实STL库里面它真正的底层实现结构是这样的:

每个容器的反向迭代器的构造,都是采用正向迭代器的end()进行构造适配,这么做只是为形成对称结构!!!只不过在用户层,看到的是上面的那两个接口那样:rbegin返回的是最后一个元素的反向迭代器,rend返回的是第一个元素的前一个理论元素的反向迭代器!这实际上也符合迭代器存在的目的:不关心底层具体实现结构,能够采用一种统一的方式去对容器中的数据进行访问!

三、以vector模拟实现为例

这里补充它的迭代器的完整实现,list也是类似的写法,因为上面的模拟实现的反向迭代器是适合所有容器的反向迭代器,只要你有正向迭代器,传进来就能适配!!

namespace Ve
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;// 反向迭代器适配支持typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;typedef Reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;          const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}// ...}
}

四、总结

①反向迭代器实际上是一个适配器,也叫迭代器适配器,适合所有容器。它实际上都是在调用对应的正向迭代器进行操作,反向的++,就是调用正向的--!

②反向迭代器本质就是对正向迭代器的一种封装!


希望今天的内容对你有帮助,感谢你的观看!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/703904.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

error Error: certificate has expired

用yarn命令安装依赖的时候遇到报错&#xff1a; 原因&#xff1a;可能是开了服务器代理访问导致ssl安全证书失效 解决方法&#xff1a; 在终端输入 yarn config set "strict-ssl" false -g yarn config set "strict-ssl" false -g 然后再安装依赖就不…

如何基于可靠事件模式实现最终一致性?

今天我们一起来探讨一个分布式环境下的常见问题,这个问题与数据的一致性有关。那么,什么是数据一致性呢?要回答这个问题,需要我们回顾一下单块系统和分布式系统中对于数据处理的不同需求。 我们知道,传统的单块系统通常都只与一个数据库进行交互,所有的数据处理过程都位于…

MS41908M替代AN41908

产品简述 MS41908M 是一款用于网络摄像机和监控摄像机的镜头 驱动芯片他可完全替代AN41908。 芯片内置光圈控制功能&#xff1b;通过电压驱动方式以及扭矩纹 波修正技术&#xff0c;实现了噪声微步驱动。 主要特点 电压驱动方式&#xff0c;256 微步驱动电路&#xff08;两通道…

LeetCode算法题:11. 盛最多水的容器(Java)(双指针问题总结)

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 提示&#xff1a; n height.length2 <…

定时发圈操作介绍

1、登陆已有的账号&#xff0c;点击到"朋友圈"功能 2、选择要发圈的微信号&#xff0c;编辑发圈的文案内容 3、自定义想要的时间点 4、点击"立即发送" 5、可进行跟圈

死锁调试技巧:工作线程和用户界面线程

有人碰到了一个死锁问题&#xff0c;找到我们想请我们看看&#xff0c;这个是关于应用程序用户界面相关的死锁问题。 我也不清楚他为什么会找上我们&#xff0c;可能是因为我们经常会和窗口管理器打交道吧。 下面&#xff0c;我们来看看死锁的两个线程。 >> 请移步至 …

pcdn边缘云常见sla有哪些?如何避免被白嫖

PCDN&#xff08;Point-to-Point Content Delivery Network&#xff09;边缘云常见的SLA&#xff08;Service Level Agreement&#xff09;规则包括高峰期离线、服务时间、重传延时、限速等。这些规则是为了保证服务质量和用户体验。下面将详细解释这些规则&#xff0c;并提供一…

【嵌入式大赛应用赛道】机械手臂

电机 进步电机&#xff1a;它的转动是以确定的步数进行的&#xff0c;只要计算好脉冲数量和频率&#xff0c;就可以准确预测和控制电机的转动角度、速度以及停止的位置 伺服电机&#xff1a;将输入的电信号&#xff08;如电压或电流指令&#xff09;转换成轴上的精确旋转运动…

stack、queue、priority_queue以及仿函数

我们上次对std中的list进行实现&#xff0c;今天我们要实现stack、queue、priority_queue以及仿函数。 目录 stack堆堆的框架构造函数push插入pop删除size()大小empty()判断空top()取栈顶的元素 queue队列队列框架问题&#xff1a; 这里我们为什么用deque? 插入删除取头数据取…

线性模型快速入门

使用matplotlib画一条直线 import numpy as np import matplotlib.pyplot as pltx np.linspace(-5, 5, 100) y 0.5*x 3plt.plot(x, y, c"orange") plt.title("Straight Line") plt.show()线性模型的直线表示 import numpy as np import matplotlib.py…

VUE如何实现批量下载多个文件并导出zip格式

效果图 1、安装jszip和file-saver插件 npm install jszip npm install file-saver2、在所需页面引入 import JSZip from "jszip"; import FileSaver from "file-saver";3、模拟fileList数组 //fileList模拟文件数组export default {name: "notic…

企业大模型如何成为自己数据的“百科全书”?

作者 | 郭炜 编辑 | Debra Chen 在当今的商业环境中&#xff0c;大数据的管理和应用已经成为企业决策和运营的核心组成部分。然而&#xff0c;随着数据量的爆炸性增长&#xff0c;如何有效利用这些数据成为了一个普遍的挑战。 本文将探讨大数据架构、大模型的集成&#xff0…