C++——反向迭代器

news2024/11/25 6:40:55

1.回顾

template<class T>
struct __list_iterator
{
	typedef list_node<T> Node;
	typedef __list_iterator<T> self;
	Node* _node;
 
	__list_iterator(Node* node)
		:_node(node)
	{}
 
	self& operator++()
	{
		_node = _node->_next;
		return *this;
	}
 
	T& operator*()
	{
		return _node->_data;
	}
 
	bool operator!=(const self& s)
	{
		return (_node != s._node);
	}
};

2.list的反向迭代器

2.1库中反向迭代器的使用

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;

	return 0;
}

2.2模拟实现

复用已经实现的迭代器实现反向迭代器

使用正向迭代器适配出反向迭代器

2.2.1反向迭代器

//reverse_iterator.h

#pragma once
//适配器模式
//使用正向迭代器适配出一个反向迭代器

// vector::iterator 适配出 vector 的 ReverseIterator
// list::iterator 适配出 list 的 ReverseIterator
// ...

template<class Iterator, class Ref, class Ptr>
class ReverseIterator
{
public:
	typedef ReverseIterator<Iterator, Ref, Ptr> Self;

	ReverseIterator(Iterator it)
		:_it(it)
	{}

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

	//普通迭代器和const迭代器的唯一区别:
	//一个是可读可写,另一个是只读的

	Ref operator*()//这里不知道T和Iterator的关系
	{
		return *_it;
	}

	Ptr operator->()
	{
		//return _it->operator();//???
		return _it.operator->();//这里只能显式调用
	}

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

private:
	Iterator _it;
};

2.2.2 list

//list.h

#pragma once
//编译器为了节省编译时间,只会向上查找
#include"reverse_iterator.h"

namespace jxy
{

template<class T>
class list//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 ReverseIterator<iterator, T&, T*> reverse_iterator;
	//反向的const迭代器
	typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;

	//普通迭代器使用普通的适配
	//const的使用const适配

	reverse_iterator rbegin()
	{
		//构造
		return reverse_iterator(--end());
	}

	reverse_iterator rend()
	{
		return reverse_iterator(end());
	}

	const_reverse_iterator rbegin() const
	{
		return const_reverse_iterator(--end());
	}

	const_reverse_iterator rend() const
	{
		return const_reverse_iterator(end());//注意end()的类型
	}

private:
	Node* _head;
	size_t _size;
};
}

2.3测试反向迭代器

int main()
{
	jxy::list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	jxy::list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	jxy::list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	return 0;
}

2.4测试const反向迭代器

void func(const jxy::list<int>& lt)
{
	jxy::list<int>::const_reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		//迭代器指向的内容不能修改
		//*rit += 10;

		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

int main()
{
	jxy::list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	func(lt);

	return 0;
}

3.vector的反向迭代器

3.1模拟实现

list迭代器类似,直接CV一份

#pragma once
#include"reverse_iterator.h"
#include<assert.h>
namespace jxy
{

	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, const T&, const 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;
		}
	};

}

此时出现了问题,编译不通过

3.2C++编译器的特殊处理

//演示这个特殊处理
class A
{
public:
	A(int a=0)
		:_a(a)
	{}

	void Print()
	{
		cout << "A" << endl;
	}

private:
	int _a;
};


int main()
{

	A();//A的一个临时对象
	//匿名对象也是一个临时对象

	那么它具不具有常性?它具有常性,证明如下:

	//A& ref = A(1);//这里不能给它取别名
	const A& ref = A(); //但加上const就可以了

	这里体现了const属性


	能不能调用非const成员函数?
	//按理说是不能的,因为有权限的放大
	A(1).Print();//但事实上却是可以调用,这就很奇怪

	这里又没有体现const属性


	可以认为这里是C++处理的一个特例
	A(1).Print();
	//因为存在使用匿名对象去调用函数的需求,所以这里做出了特殊处理

	return 0;
}

3.3修改

所以要对vector的反向迭代器进行修改。

list的反向迭代器也可以修改,但要重载运算符 - ,而且在意义上是不建议重载的

#pragma once
#include"reverse_iterator.h"
#include<assert.h>
namespace jxy
{

	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, const T&, const T*> const_reverse_iterator;

		reverse_iterator rbegin()
		{
			//构造
			//return reverse_iterator(--end());
			return reverse_iterator(end()-1);
			//所以这里改为减一即可
		}

		reverse_iterator rend()
		{
			//return reverse_iterator(--begin());
			return reverse_iterator(begin()-1);
		}

		const_reverse_iterator rbegin() const
		{
			//return const_reverse_iterator(--end());
			return const_reverse_iterator(end()-1);
		}

		const_reverse_iterator rend() const
		{
			//return const_reverse_iterator(--begin());
			return const_reverse_iterator(begin()-1);
		}

		//注意:越界不是在编译时报错

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}
	};
}


int main()
{
//就和这里类似

	int a = 10;
	--a;//变量可以--
	a - 1;//也可以-1

	//--10;  //报错,10是常量
	10 - 1;//可以 

	return 0;
}

3.4测试反向迭代器

void func(const jxy::vector<int>& lt)
{
	jxy::vector<int>::const_reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		//迭代器指向的内容不能修改
		//*rit += 10;

		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}


int main()
{
	jxy::vector<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	func(lt);

	return 0;
}

4.SGI版本库中反向迭代器的实现

乍看库中的实现,vector会越界

list没有访问到第一个值,而且访问了哨兵位,是随机值

但实际上,这只是另外一种实现方式,它拥有自己的优势

为避免上述情况,在其中访问元素时,访问的是前一个位置

5.依照库中的思路再次模拟实现

5.1反向迭代器

//reverse_iterator.h

#pragma once


template<class Iterator, class Ref, class Ptr>
class ReverseIterator
{
public:
	typedef ReverseIterator<Iterator, Ref, Ptr> Self;

	ReverseIterator(Iterator it)
		:_it(it)
	{}

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

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

	Ref operator*()
	{
		Iterator cur = _it;
		return *(--cur);
	}

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

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

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

private:
	Iterator _it;
};

5.2vector反向迭代器

#pragma once
#include"reverse_iterator.h"
#include<assert.h>

namespace jxy
{

	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, const T&, const 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;
		}
	};
}

5.3list反向迭代器

//list.h

#pragma once
#include"reverse_iterator.h"

namespace jxy
{

template<class T>
class list//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 ReverseIterator<iterator, T&, T*> reverse_iterator;
	//反向的const迭代器
	typedef ReverseIterator<const_iterator, const T&, const 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());
	}

private:
	Node* _head;
	size_t _size;
};
}

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

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

相关文章

C# 删除插入-列表排序字典

C# 删除插入-列表排序字典 测试文件 using System; using System.Collections; using System.Collections.Generic;using

五、Linux之Vi和Vim编辑器

基本介绍 Vi Linux 系统会内置 vi 文本编辑 Vim 具有程序编辑的能力&#xff0c;可以看做是 Vi 的增强版本&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。 代码补完、编译及错误跳转等方便编程的功能特别丰富 常用的三种模式 正常模式 以 vim …

如何将 html 渲染后的节点传递给后端?

问题 现在我有一个动态的 html 节点&#xff0c;我想用 vue 渲染后&#xff0c;传递给后端保存 思路 本来想给html的&#xff0c;发现样式是个问题 在一个是打印成pdf&#xff0c;然后上传&#xff0c;这个操作就变多了 最后的思路是通过 html2canvas 转化成 canvas 然后变成…

鸿蒙--WaterFlow 实现商城首页

目录结构 ├──entry/src/main/ets // 代码区 │ ├──common │ │ ├──constants │ │ │ └──CommonConstants.ets // 公共常量类 │ │ └──utils │ │ └──Logger.ets // 日志打印类 │ ├──entryability │ │ └──EntryAbility.ets // 程序入口…

TypeScript 中命名空间与模块的理解及区别

文章目录 一、模块&#xff08;Modules&#xff09;示例 二、命名空间&#xff08;Namespaces&#xff09;示例 三、区别 一、模块&#xff08;Modules&#xff09; 在 TypeScript 中&#xff0c;任何包含顶级 import 或 export 声明的文件都被视为一个模块。模块的特点是它有…

未来的电影:人机环境生态系统智能

本文摘自《影视产业研究》2024年10月创刊号 摘要: 随着人工智能的快速发展&#xff0c;未来的电影得到了广泛关注。通过对未来电影相关研究提供了一种将人机环境系统智能与影游结合的方式来解决未来电影的瓶颈问题&#xff0c;并从态势感知相关研究角度进行了研究。鉴于此&…

阿里云等联合编写的《2024大模型典型示范应用案例集》(附PDF分享)

这份大模型案例集资料已经上传CSDN&#xff0c;朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】 2024 年是大模型深入赋能千行百业&#xff0c;融入实体经济&#xff0c;助力科技创新的一年。截至今年5月&#xff0c;我国国产大模型的数量已经超过…

taozige/基于Java语言的充电桩平台+充电桩系统+充电桩管理系统+充电桩系统源码+充电桩管理后台+充电桩小程序

简述 SpringBoot 框架&#xff0c;充电桩平台充电桩系统充电平台充电桩互联互通协议云快充协议1.5新能源汽车电动自行车公交车-四轮车充电充电源代码充电平台源码Java源码无加密项目 介绍 云快充协议云快充1.5协议云快充协议开源代码云快充底层协议云快充桩直连桩直连协议充…

Python人脸识别实战——基于Dlib和OpenCV的人脸识别与关键点检测(附完整代码和结果图)

Python人脸识别实战——基于Dlib和OpenCV的人脸识别与关键点检测&#xff08;附完整代码和结果图&#xff09; 关于作者 作者&#xff1a;小白熊 作者简介&#xff1a;精通python、matlab、c#语言&#xff0c;擅长机器学习&#xff0c;深度学习&#xff0c;机器视觉&#xff0…

基于FPGA的以太网设计(一)

以太网简介 以太网&#xff08;Ethernet&#xff09;是一种计算机局域网技术。IEEE组织的IEEE 802.3标准制定了以太网的技术标准&#xff0c;它规定了包括物理层的连线、电子信号和介质访问控制的内容。以太网是目前应用最普遍的局域网技术&#xff0c;取代了其他局域网标准如…

在线深度学习:爱奇艺效果广告分钟级模型优化

01# 背景 在效果广告投放场景中&#xff0c;媒体侧需要准确衡量每次请求的价值&#xff0c;模型预估值在广告竞价中扮演着核心角色。模型预估精度的提升&#xff0c;是改善媒体侧变现效率、提升广告收益的核心技术驱动力。 此前&#xff0c;爱奇艺效果广告预估模型为小时级模型…

爬虫设计思考之二

“所谓爬虫,其本质是一种计算机程序,它的行为看起来就像是蜘蛛在网上面爬行一样,顺着互联网这个“网”,一条线一条线地“爬行”。 一、认识爬虫 爬虫这个词对于非专业人士比较的陌生&#xff0c;但是实际却和我们的生活息息相关。例如我们国内经常使用的百度浏览器搜索&#x…

Qt-系统处理鼠标相关事件(57)

目录 使用 按下事件 释放事件 双击事件 移动事件 滚轮事件 使用 按下事件 实现下面的功能 鼠标在此处点击&#xff0c;就可以获取鼠标位置 添加函数 提升函数 手册中找到这个函数的原型 重写该函数 定义 重写 这里有一个细节需要注意&#xff0c;因为这里的标准点击…

单服务器基于 Nginx 负载均衡 + Docker Compose 提高并发量

背景信息 开发需求 单服务器的多服务管理 多服务器的集群管理可参考博主 docker swarm 的技术分享《基于 docker swarm 和 NVIDIA MIG 部署并行 AI 推理服务》 根据服务请求量和服务器规模的匹配程度&#xff0c;多服务器集群的性能对于目前来说过剩&#xff0c;故有了本研究的…

c#-出现类型初始值设定项引发异常的解决方案

当出现该问题时&#xff0c;通常摸不着头脑&#xff0c;无法定位到该问题所在行。 我们可以找到应发异常的类&#xff0c;例如我上面类为YY_Model.DefaultConfig。 打开这个类文件&#xff0c;加一个断点&#xff0c;一行行运行&#xff0c;到哪里突然跳出该文件&#xff0c;则…

Python脚本实现发送QQ邮件

需要发件人邮箱地址、授权码和收件人邮箱地址 1、登录QQ邮箱后台&#xff0c;点击右上角设置&#xff0c;下拉找到第三方服务&#xff0c;开启SMTP服务&#xff0c;复制生成的授权码 2、新建一个python文件&#xff0c;输入以下源码&#xff0c;更替参数后运行即可 import smt…

【计算机网络 - 基础问题】每日 3 题(三十六)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

无缝数据流动:跨域数据交换的高效策略

大型企业为了业务拓展需要&#xff0c;会在全国乃至全球各地设立分公司和办事机构&#xff0c;以便更好地处理当地事务&#xff0c;并进行市场的开拓和客户维护&#xff0c;因此大型企业都会面临跨域数据交换的场景。 跨域数据交换时&#xff0c;需要考虑多方面的问题&#xff…

使用机器学习边缘设备的快速目标检测

论文标题&#xff1a;Fast Object Detection with a Machine Learning Edge Device 中文标题&#xff1a;使用机器学习边缘设备的快速目标检测 作者信息&#xff1a; Richard C. Rodriguez, MSDA Information Systems and Cyber Security Department, The University of Tex…

IEEE新晋“水刊”,非OA,2个月可录,毕业神刊比《IEEE Access》更保险!

本期解析&#xff1a;综合类 本期解析IEEE旗下的【综合类-仪器仪表】SCI 优点&#xff1a; 审稿速度快&#xff0c;快的2-4个月录用&#xff1b; 非OA&#xff0c;国人友好&#xff0c;录用率高&#xff1b; 缺点&#xff1a; 出版周期可能较长 期刊简介 IEEE Sensors Jou…