反向迭代器reverse_iterator模拟实现

news2025/7/10 11:57:12

准备工作

  1. 相同的命名空间可以分割在不同的文件中,编译器最后都会合成在同一个命名空间下。
  2. 我们的reverse_iterator是个适配器,为什么叫适配器,是因为它需用正向迭代器做适配。简言之,反向迭代器通过正向迭代器做实例化会减少很多冗余且方便很多。
  3. 把reverse_iterator放在另外一个.h头文件中,而我们将把这个头文件引入到list.h中,给list造一个反向迭代器。

反向迭代器模拟实现

  • 反向迭代器与正向迭代器的关系:
    STL源码中如下:
    请添加图片描述
    正向和反向迭代器的begin()和end()相反,是对称的,这种关系使得反向迭代器解引用时,我们应该往前倒一下,再解引用。

  • 模板使用
    因为需要用正向迭代器来适配,此外还要考虑==const类型反向迭代器(因为像重载解引用函数和重载->不能构成函数重载,因为这里不传参,只是返回值类型不同)。==所以参数为:正向迭代器、引用、指针。

  • 成员变量:
    显然,它需要一个正向迭代器作为成员变量,我们的构造函数就以正向迭代器来初始反向迭代器。做成员变量的赋值即可。

  • operator*()
    我们要的是解引用当前迭代器,应该返回引用,因为需要有修改值本身的权限,且正向迭代器返回重载*返回的也是引用,所以这里继续用引用Ref,此外。此外,因为和正向迭代器相反,解引用应该给前面倒一个

Ref operator*()
{
	Iterator tmp = _it;
	return *(--tmp);
}
  • operator->()
    指向节点存着对象时,我们要对象指针,也就是对象地址,所以要先解引用再取&。
Ptr operator->()
{
	return &(operator*());
}
  • operator++()
    ++反向迭代器我们应该让成员变量正向迭代器做–。(我之前发现运行出错是因为我的正向迭代器–写错了),先–,再解引用,要的是迭代器对象,所以返回*this,用引用类型接收。
Self& operator++()
{
	--_it;
	return *this;
}
  • operator–()
    同++相反
Self& operator--()
{
	++_it;
	return *this;
}
#pragma once
#include<iostream>
using namespace std;

// 在别的文件中也可以起同名的命名空间,且在别的文件中兼容
namespace lz
{
	// 适配器 -- 复用	:在声明处给的iterator 比如list那里的iterator
	/* 
		在list中 有如下的情况 
	// 反向迭代器也分普通和cosnt类型
        typedef ListIterator<iterator, T&, T*> riterator;
        typedef ListIterator<const_iterator, const T&, const T&> const_riterator;
	*/
	template<class Iterator, class Ref, class Ptr>
	struct Reverse_iterator
	{
		Iterator _it;	// 正向迭代器类 
		typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
		Reverse_iterator(Iterator it)
			:_it(it)
		{}

		// 使用模板还是为了区分const和普通类型迭代器,因为无参 所以不能通过传参构成重载
		// 因为返回的是解引用,正向迭代器解引用返回的是&类型,所以这里引用接可以 且就是要修改,得引用,且这里是迭代器
		Ref operator*()
		{
			Iterator tmp = _it;
			return *(--tmp);
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		// Self:因为++、--运算要返回迭代器对象
		// 引用:因为需要要对存的值有修改权限	且是*this,它配
		// 返回迭代器对象	反向的++,需要对正向--,再解引用
		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		bool operator!=(const Self& s)
		{
			return _it != s._it;
		}
	};
}

调用方:list代码节选

  • 分析:
  1. 关于typedef:如下我们需要利用riterator,这里Reverse_iterator虽然在不同.h文件,但是我们写同一个命名空间lz,运行起来就会合并,所以这里我看的视频里面没有报错,而我先报错了,因为我写了两个不同命名空间。
  2. rbegin():
    反向迭代器类型的函数,我们返回反向迭代器类型rit,但是是要用正向迭代器来实例化反向迭代器,而直接给end()即可,因为对称。STL源码中就是这样的设计,巧妙的设计使得代码简单优雅。
  3. rend():
    同rbegin(),但是以正向迭代器的begin()方法初始化即可。
public:
        // 两个的作用
        typedef ListIterator<T, T&, T*> iterator;

        typedef ListIterator<T, const T&, const T&> const_iterator;

        // 反向迭代器也分普通和cosnt类型
        typedef Reverse_iterator<iterator, T&, T*> riterator;

        typedef Reverse_iterator<const_iterator, const T&, const T&> const_riterator;
==下面是begin和end==
iterator begin()
        {
            return iterator(_pHead->_pNext);
        }

        // list的end()其实是头节点,这里不存值。
        // 不用引用,因为返回的是临时变量。不是类成员变量,只有类成员变量,才有资格。如:*this等
        iterator end()
        {
            return iterator(_pHead);
        }
// =====    反向迭代器:普通和const可以重载,因为参数后面加了const,符合重载条件    =======
        riterator rbegin()
        {
            return riterator(end());
        }

        riterator rend()
        {
            return riterator(begin());
        }


  • 分析:

运行效果:

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Fragstats的土地利用景观格局分析

景观格局及相关软件介绍 Fragstats界面与数据格式 数据准备&#xff1a;ArcGIS软件操作 数据准备&#xff1a;数据结构及变换 数据准备&#xff1a;数据投影及变换 数据准备&#xff1a;数据采集与编辑 数据准备&#xff1a;数据获取及处理 土地利用统计分析 Fragstats…

微服务(一) —— 概念

目录1. 什么是微服务2. springcloud3. 服务提供者、服务消费者1. 什么是微服务 微服务&#xff1a; 分布式架构的一种。 服务集群&#xff1a;将一个功能复杂的项目拆分成许多个独立的项目&#xff08;称为服务&#xff0c;每部分完成一定的功能&#xff09;&#xff0c;并进…

继承、多态、组合(Java系列5)

目录 前言&#xff1a; 1.继承 1.1继承的概念 1.2继承的语法 1.3父类成员访问 1.4super关键字 1.5super和this 1.6继承关系的执行顺序 1.7继承方式 1.8final关键字 2.继承与组合 3.多态 3.1多态的概念 3.2多态实现的条件 4.重写 4.1重写的概念 4.2方法重写的规…

前端基础(十五)_多栏布局(两列自适应布局、圣杯布局---三列布局、双飞翼布局--三列布局、等高布局)

什么是自适应&#xff1f; 自适应&#xff1a;让同一个页面自动适应不同大小的设备&#xff0c;从而解决为不同设备提供不同版本页面的问题。 自适应布局&#xff1a;解决在不同大小的设备上呈现相同网页的问题 两列自适应布局 1、Html结构中–左右两个盒子&#xff1b; 2、…

UT斯达康MC8638S-高安-S905-河北联通-破解刷机线刷固件包

UT斯达康MC8638S-高安-S905-河北联通-破解刷机线刷固件包 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;不在被强制升级&#xff1b; 4、大…

远离不恰当的运动方式,缤跃酒店满足大众对专业化、品质化健身场所的需求!

2022年&#xff0c;各大新闻平台关于“横纹肌溶解综合征”的新闻报道屡见不鲜&#xff0c;横纹肌溶解是一种因肌肉组织严重受损导致的综合征&#xff0c;严重的可能会出现急性肾损伤、心律失常&#xff0c;甚至死亡。探究原因&#xff0c;这些患者多是由于运动过量或不当被送入…

深度解读|NebulaGraph x 阿里云计算巢,云上构建超大规模图数据库

近期&#xff0c;杭州悦数科技有限公司与阿里云计算巢达成合作&#xff0c;NebulaGraph 作为首款图数据库产品正式入驻阿里云计算巢&#xff0c;为用户带来了云端一键部署企业级图数据库集群的全新体验。同时&#xff0c;该服务集成了多款 NebulaGraph 周边可视化图数据库管理工…

python-面向对象

目录 面向对象 封装 继承 重写 重载 多态 单下划线、双下划线、头尾双下划线说明&#xff1a; 面向对象 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。类变量&#xff1a;类变量在整个实例化的对…

ENSP防火墙进入web登陆界面

步骤 新建拓扑【选择USG6000V】然后导入USG6000V得镜像包进入到防火墙的CLI界面 账户与密码 账户&#xff1a;admin 密码Admin123&#xff08;密码输入不会显示&#xff09; 输入正确账户密码后会提醒修改密码输入 y 回车后提醒如下&#xff1a; 输入旧密码 输入新密码&…

基于禁忌搜索的TSP问题求解仿真输出路线规划图和收敛曲线

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 禁忌搜索&#xff08;Tabu Search或Taboo Search&#xff0c;简称TS&#xff09;是对局部搜索&#xff08;LS&#xff09;的一种扩展&#xff0c;是一种全局寻优算法&#xff0c;其特点是采用禁忌…

践行者访谈实录:你真的了解CMMI吗?

2022年12月21日晚8点&#xff0c;我参与了《践行者》访谈节目&#xff0c;历时2小时&#xff0c;就CMMI有关的话题和主持人徐东伟老师&#xff0c;和热心的听众进行了在线交流。节目结束后&#xff0c;禅道公司的小朋友们整理了文字记录如下。 相信大家对CMMI的认知或多或少地…

Android自定义ViewGroup的布局,往往都是从流式布局开始

前言 前面几篇我们简单的复习了一下自定义 View 的测量与绘制&#xff0c;并且回顾了常见的一些事件的处理方式。 那么如果我们想自定义 ViewGroup 的话&#xff0c;它和自定义View又有什么区别呢&#xff1f;其实我们把 ViewGroup 当做 View 来用的话也不是不可以。但是既然…

端到端网络全链路监控方案

结构日渐复杂&#xff0c;设备类型、设备数量逐渐增加&#xff0c;设备间的连接关系随之复杂化&#xff0c;同时随着无线网络的发展&#xff0c;网络中的连接关系逐渐去“线”化&#xff0c;如何可观、高效的对网络间复杂的连接关系进行监控和管理&#xff0c;成为用户不可忽视…

2022年最好用的五款设备管理软件

工厂是典型的设备密集型组织&#xff0c;设备固定资产具有数量多、种类多、使用周期长、使用地点分散等特征。如果依然在使用传统的手工记录数据、手工巡检、纸质维保、电话维修的方式&#xff0c;势必给企业带来损失。 设备是众多企业经营中支出的主要组成部分&#xff0c;在…

(二十)Vue之非单文件组件

文章目录基本使用一、如何定义一个组件&#xff1f;二、如何注册组件&#xff1f;三、如何使用组件&#xff1f;演示程序普通Vue程序单文件组件程序局部注册全局注册几个注意点1.关于组件名2.关于组件标签3.一个简写方式组件的嵌套使用关于VueComponent一个重要的内置关系&…

Shape详解

Spape详解 1.自定义背景shape 1.1gradient 1.简介 定义渐变色&#xff0c;可以定义两色渐变和三色渐变&#xff0c;及渐变样式&#xff0c;它的属性有下面几个2.属性 angle&#xff0c;只对线性渐变是有效的放射性渐变必须指定放射性的半径&#xff0c;gradientRadiouscentetX和…

Ubuntu安装redis服务器

官网下载redis服务器的压缩包redis-6.0.16.tar.gz 点击download 6.2.8或任意版本即可。 上传下载的压缩包到服务器或者本地虚拟机 解压压缩包&#xff0c;并安装gcc tar -zxvf redis-6.0.16.tar.gz解压之后可以看到redis的目录结构&#xff1a; 没有bin目录&#xff0c;而redi…

Meta CTO专访:2023年AR/VR、元宇宙的下一步怎么走

2022年对于Meta来说注定是不平凡的一年&#xff0c;它经历了股价大跌、万人大裁员、项目重组、季度营收首次下滑、Reality Labs季度亏损破纪录&#xff0c;甚至前不久Meta AR/VR业务的元老级人物、Reality Labs顾问CTO John Carck也宣布离职&#xff0c;这件事对于Meta甚至整个…

HEVC学习之CTU划分

一,CTU相关概念 H.265将图像划分为“树编码单元&#xff08;coding tree units, CTU&#xff09;”&#xff0c;而不是像H.264那样的1616的宏块。根据不同的编码设置&#xff0c;树编码块的尺寸可以被设置为6464或有限的3232或1616。 上图就是一个6464树编码块的分区示例&am…

数字ic验证|SoC的功能验证

随着设计的进行&#xff0c;越接近最后的产品&#xff0c;修正一个设计缺陷的成本就会越高。 1.功能验证概述 在IC设计与制造领域&#xff0c;通常所说的验证&#xff08;Verification&#xff09;和测试&#xff08;Test&#xff09;是两种不同的事 验证 在设计过程中确认…