STL-迭代器

news2024/10/6 16:22:17

1.迭代器

1.1正向迭代器

正向迭代器是用一个类封装的,迭代器类。例如:在vector,string中的迭代器就相当于一个指针,在list类中用一个类来封装一个节点,实质上也还是一个指针,迭代器就相当于指向一个节点的指针。

现在以list为例子,list的迭代器,代码如下:

//迭代器类
// 一个链表指针用迭代器封装,实质上还是一个指针
//迭代器也就相当于指向一个节点的指针
//第一种解决const类型的迭代器
//const迭代器类
template<class T>
struct ListConstIterator
{
	typedef ListNode<T> Node;
	typedef ListIterator<T> Self;

	Node* _node; //一个迭代器节点

	//迭代器构造
	ListConstIterator(Node* node) :_node(node)
	{}

	++it
	前置++,返回++以后的值
	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}

	it++
	后置++
	Self operator++(int)
	{
		Self tmp(*this);//浅拷贝,即两个迭代器指针指向同一个空间,直接应用默认拷贝构造
		_node = _node->_next;
		return tmp;//拷贝
	}

	--it
	Self& operator--()
	{
		//向前走
		_node = _node->_prev;
		return *this;
	}

	it--
	Self operator--(int)
	{
		Self tmp(*this);
		_node = _node->_prev;
		return tmp;
	}

	*it
	解引用,返回的是数据
	T& operator*()
	{
		return _node->data;
	}

	==
	比较两个迭代器相等,即比较迭代器的位置(引用/地址)相同
	bool operator==(const Self& it)
	{
		return _node == it._node;
	}

	//!=
	bool operator!=(const Self& it)
	{
		return _node != it._node;
	}

	//->
	//返回的是数据的地址
	T* operator->()
	{
		return &_node->data;
	}
};

1.3 正向const迭代器

const迭代器和普通迭代器区别是: const迭代器指向的内容不能被修改!即为const_iterator begin() const,相当于const int *p
而迭代器器本身不能修改是const iterator begin(),也就相当于int * const p
所以普通迭代器和const迭代器的代码差异只在解引用是有差别
第一种解决方法是在普通迭代器的基础上再写一个const迭代器类,代码如下:

普通迭代器:

//const迭代器类
template<class T>
struct ListConstIterator
{
	typedef ListNode<T> Node;
	typedef ListIterator<T> Self;

	Node* _node; //一个迭代器节点

	//迭代器构造
	ListConstIterator(Node* node) :_node(node)
	{}

	++it
	前置++,返回++以后的值
	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}

	it++
	后置++
	Self operator++(int)
	{
		Self tmp(*this);//浅拷贝,即两个迭代器指针指向同一个空间,直接应用默认拷贝构造
		_node = _node->_next;
		return tmp;//拷贝
	}

	--it
	Self& operator--()
	{
		//向前走
		_node = _node->_prev;
		return *this;
	}

	it--
	Self operator--(int)
	{
		Self tmp(*this);
		_node = _node->_prev;
		return tmp;
	}

	*it
	解引用,返回的是数据
	T& operator*()
	{
		return _node->data;
	}

	==
	比较两个迭代器相等,即比较迭代器的位置(引用/地址)相同
	bool operator==(const Self& it)
	{
		return _node == it._node;
	}

	//!=
	bool operator!=(const Self& it)
	{
		return _node != it._node;
	}

	//->
	//返回的是数据的地址
	T* operator->()
	{
		return &_node->data;
	}
};

const迭代器

//第一种解决const类型的迭代器
//const迭代器类
template<class T>
struct ListConstIterator
{
	typedef ListNode<T> Node;
	typedef ListConstIterator<T> Self;

	Node* _node; //一个迭代器节点

	//迭代器构造
	ListConstIterator(Node* node) :_node(node)
	{}

	++it
	前置++,返回++以后的值
	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}

	it++
	后置++
	Self operator++(int)
	{
		Self tmp(*this);//浅拷贝,即两个迭代器指针指向同一个空间,直接应用默认拷贝构造
		_node = _node->_next;
		return tmp;//拷贝
	}

	--it
	Self& operator--()
	{
		//向前走
		_node = _node->_prev;
		return *this;
	}

	it--
	Self operator--(int)
	{
		Self tmp(*this);
		_node = _node->_prev;
		return tmp;
	}

	*it
	解引用,返回的是数据
	const T& operator*()
	{
		return _node->data;
	}

	==
	比较两个迭代器相等,即比较迭代器的位置(引用/地址)相同
	bool operator==(const Self& it)
	{
		return _node == it._node;
	}

	//!=
	bool operator!=(const Self& it)
	{
		return _node != it._node;
	}

	//->
	//返回的是数据的地址
	const T* operator->()
	{
		return &_node->data;
	}

};

第二种解决方法:由于const迭代器和普通迭代器只有解引用重载的返回值不一样

//普通迭代器
解引用,返回的是数据
	T& operator*()
	{
		return _node->data;
	}

	//->
	//返回的是数据的地址
	T* operator->()
	{
		return &_node->data;
	}
//const迭代器
解引用,返回的是数据
	const T& operator*()
	{
		return _node->data;
	}
	
	//->
	//返回的是数据的地址
	const T* operator->()
	{
		return &_node->data;
	}

由于两个代码差别不大,只是重载的返回值不一样。第一种也会导致代码冗余,所以用模板来解决以下的问题,代码如下:

template<class T,class Ref,class Ptr>
struct ListIterator
{
	typedef ListNode<T> Node;
	typedef ListIterator<T,Ref,Ptr> Self;

	Node* _node; //一个迭代器节点

	//迭代器构造
	ListIterator(Node *node):_node(node)
	{}

	++it
	前置++,返回++以后的值
	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}

	it++
	后置++
	Self operator++(int)
	{
		Self tmp(*this);//浅拷贝,即两个迭代器指针指向同一个空间,直接应用默认拷贝构造
		_node = _node->_next;
		return tmp;//拷贝
	}

	--it
	Self& operator--()
	{
		//向前走
		_node = _node->_prev;
		return *this;
	}

	it--
	Self operator--(int)
	{
		Self tmp(*this);
		_node = _node->_prev;
		return tmp;
	}

	*it
	解引用,返回的是数据
	//T& operator*()
	Ref operator*()
	{
		return _node->data;
	}

	==
	比较两个迭代器相等,即比较迭代器的位置(引用/地址)相同
	bool operator==(const Self& it)
	{
		return _node == it._node;
	}

	//!=
	bool operator!=(const Self& it)
	{
		return _node != it._node;
	}

	//->
	//返回的是数据的地址
	//T* operator->()
	Ptr operator->()
	{
		return &_node->data;
	}
};


template<class T>
class list
{
public:
	//重定义节点类名
	typedef ListNode<T> Node;
private:
	Node* _head;//哨兵位
	size_t _size;//链表中节点的个数

public:
	......
	//第二种方法解决const迭代器类
	typedef ListIterator<T,T&,T*> iterator;
	typedef ListIterator<T,const T&,const T*> const_iterator;
	
	//迭代器的引用
	iterator begin()
	{
		//iterator it(_head->_next);//有名对象
		//return it;
		return iterator(_head->_next);//这是应用的是一个匿名对象
	}

	iterator end()
	{
		return iterator(_head);
	}

	//const迭代器,需要迭代器不能修改,还是迭代器指向的内容?
	// 迭代器指向的内容不嫩被修改! const iterator不是我们需要的const迭代器
	//以下是迭代器本身不能修改
	//const iterator begin()错误
	const_iterator begin() const
	{
		//iterator it(_head->_next);//有名对象
		//return it;
		return const_iterator(_head->_next);//这是应用的是一个匿名对象
	}

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

1.3反向迭代器和反向const迭代器

在我们主观意识上,正向迭代器的begin指向的是除去哨兵位的第一个节点,end则是指向最后一个节点下一个节点(即哨兵位头节点)。而我们也会觉得rbegin则是指向最后一个数据,rend指向第一个节点的上一个节点(即哨兵位头节点),如图
反向迭代器

但是,在c++库中我们则见到的是将begin和rend指向的第一个节点,end和rbegin都指向哨兵位头节点,如图
C++库中的反向迭代器
但是库中的解引用时,会是先++,再解引用

//解引用
Ref operator*()
{
	//return *_it;
	//解引用的是前一个
	Iterator tmp = _it;
	return *(--tmp);
}
#include<iostream>
#include<vector>
#include<string>
using namespace std;

//所有容器的反向迭代器
//迭代器适配器

	//给我vector<T>::iterator,list<int>::iterator
	//适配出相应的反向迭代器
	//本来,每个容器都要写一个反向迭代器的类,但是自己写,太费劲了
	template<class Iterator, class Ref, class Ptr>
	struct ReverseIterator
	{
		typedef ReverseIterator<Iterator, Ref, Ptr> Self;//重命名

		Iterator _it;
		//构造
		//反向迭代器封装一个正向迭代器
		ReverseIterator(Iterator it) :_it(it)
		{}

		Ref operator*()
		{
			//return *_it;
			//解引用的是前一个
			Iterator tmp = _it;
			return *(--tmp);
		}

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

		//++调用迭代器中的--
		Self& operator++()
		{
			--_it;
			return *this;
		}

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

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

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

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

相关文章

Ueditor中集成135编辑器

一、背景 在资讯项目平台运营过程中&#xff0c;资讯需要排版&#xff0c;一般都是在135编辑器排好以后&#xff0c;复制到平台中UEditor编辑器中&#xff0c;所以&#xff0c;他们建议集成一下135哈 二、了解135编辑器 开始调研了解135编辑器&#xff0c;发现人家就支持集成…

系统架构师考点--系统配置与性能评价

大家好。今天我们来总结一下系统配置与性能评价的考点内容&#xff0c;这一部分一般是出在上午场的选择题中&#xff0c;占1-2分左右。 一、性能指标 计算机 对计算机评价的主要性能指标有&#xff1a;时钟频率(主频)&#xff1b;运算速度&#xff1b;运算精度内存的存储容量…

通达信机构买卖抓牛指标公式源码

通达信机构买卖抓牛指标公式源码&#xff1a; X_1:V/CLOSE/2; X_2:SUM(IF(X_1>100 AND CLOSE>REF(CLOSE,1),X_1,0),0); X_3:SUM(IF(X_1>100 AND CLOSE<REF(CLOSE,1),X_1,0),0); X_4:SUM(IF(X_1<100 AND CLOSE>REF(CLOSE,1),X_1,0),0); X_5:SUM(IF(X_1&l…

涉案财物管理系统|DW-S405系统实现涉案财物科学化管理

随着社会的不断发展&#xff0c;犯罪形式日益复杂&#xff0c;涉案财物的种类和数量也不断增加。传统的涉案财物管理方式已经无法满足现代执法办案的需求。因此&#xff0c;建立一套科学、高效、规范的警用涉案财物管理系统成为公安机关亟待解决的问题。 涉案财物管理系统DW-S…

sheng的学习笔记-AI-K均值算法

ai目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 需要学习前置知识&#xff1a;聚类&#xff0c;可参考 sheng的学习笔记-聚类(Clustering)-CSDN博客 目录 什么是k均值算法 流程 伪代码 数据集 伪代码 代码解释 划分示意图 优化目标 随机初始化 选择聚类数…

快来看,错过了今天就要设置为vip文章了----openEuler:智能算力时代的数字基础设施底座

会议主题&#xff1a;openEuler2024全球发展展望与战略规划 OpenEuler2024项目在2024年成功推出了多个长期支持&#xff08;LTS&#xff09;版本&#xff0c;标志着其在智能技术领域的全新篇章&#xff0c;并致力于构建全球性的开源新生态。以下是该项目的主要内容和成就概览&a…

ARM裸机:地址映射

S5PV210的地址映射详解 什么是地址映射&#xff1f; S5PV210属于ARM Cortex-A8架构&#xff0c;32位CPU&#xff0c;CPU设计时就有32根地址线&32根数据线。 32根地址线决定了CPU的地址空间为4G&#xff0c;那么这4G空间如何分配使用&#xff1f;这个问题就是内存映射问题。…

运算放大器输入、输出、单电源和轨到轨问题

单电源运算放大器问题 由于市场需求&#xff0c;单电源供电已成为一项日益重要的要求。汽车、机顶盒、照相机/摄像机、PC和笔记本电脑应用要求IC供应商提供各种采用单电源轨供电&#xff0c;而性能则与双电源器件相同的线性器件。功耗现已成为线路或电池供电系统的关键参数&am…

meizu M10 魅蓝 10 mblu10 root 解锁 安装LSPosed框架 紫光展锐改串 AT命令 一键新机 改机软件 硬改 改参数

meizu M10 魅蓝 10 mblu10 root 解锁 安装LSPosed框架 紫光展锐改串 AT命令 一键新机 改机软件 硬改 改参数 ro.system.build.version.release11 ro.system.build.version.release_or_codename11 ro.system.build.version.sdk30 ro.system.custom.versionAndroid_M01 ro.prod…

rk3568 OpenHarmony 串口uart与电脑通讯开发案例

一、需求描述&#xff1a; rk3568开发板运行OpenHarmony4.0&#xff0c;通过开发板上的uart串口与电脑进行通讯&#xff0c;相互收发字符串。 二、案例展示 1、开发环境&#xff1a; &#xff08;1&#xff09;rk3568开发板 &#xff08;2&#xff09;系统&#xff1a;OpenHar…

桃园三结义 | 第1集 | 三人一条心,黄土变成金,有你带着俺,大事定能成功啊!| 正所谓择木之禽,得其良木,择主之臣,得遇明主 | 三国演义 | 群雄逐鹿

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;这篇博客是毛毛张结合三国演义原著分享三国演义文学剧本中的经典台词和语句&#xff0c;本篇分享的是《三国演义》第Ⅰ部分《群雄逐鹿》的第1️⃣集《桃…

薄冰英语语法学习--名词2-格

名词后面 s&#xff0c;代表后面这个东西属于前面的。 比如toms book&#xff0c;汤姆的书。 末尾是s&#xff0c;那么直接在最后加就行了。比如boys&#xff0c;男孩们的 表示几个词共同 的所有关系在最后一个词的词尾加 sMary and Toms books 玛丽和汤姆共有的书表示几个词…

风水研究会官网源码系统-可展示自己的领域内容-商品售卖等

一款用于展示风水行业&#xff0c;周易测算行业&#xff0c;玄学行业的系统&#xff0c;并支持售卖自己的商品。 整洁大气&#xff0c;非常漂亮&#xff0c;前端内容均可通过后台修改。 大致功能&#xff1a; 支持前端内容通过后端自定义支持开启关闭会员功能&#xff0c;会…

基于PHP的初中数学题库管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的初中数学题库管理系统 一 介绍 此初中数学题库管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;系统角色分为学生&#xff0c;教师和管理员。(附带参考设计文档) 技术栈&#xff1a;phpmysqlphpstudyvscode 二 功能 …

电子电器及家电制造行业MES系统解决方案介绍

电子电器及家电制造行业是一个技术高度密集、生产工艺复杂且市场需求变化迅速的行业。为了提升生产效率、保证产品质量并快速响应市场变化&#xff0c;越来越多的电子电器及家电制造企业引入了MES系统。本文将详细介绍MES系统在电子电器及家电制造行业的应用方法及其价值。 一…

C++11 右值引用和移动语义,完美转发和万能引用,移动构造和移动赋值,可变参数模板,lambda表达式,包装器

文章目录 C11简介统一的列表初始化&#xff5b;&#xff5d;初始化std::initializer_list声明autodecltypenullptr 范围for循环 智能指针STL中一些变化右值引用和移动语义左值引用和右值引用左值引用与右值引用比较 右值引用使用场景和意义右值引用引用左值及其一些更深入的使用…

大数据------JavaWeb------Maven(完整知识点汇总)

额外知识点 IDE IDE是集成开发环境的缩写&#xff0c;它是一种软件应用程序&#xff0c;提供了编码、调试和部署软件的一站式解决方案。这些功能集成在一起&#xff0c;使开发人员能够在一个环境中完成整个软件开发过程&#xff0c;从编写代码到调试和测试&#xff0c;直到最终…

机械装备制造行业MES,实时监控生产流程

装备制造行业MES&#xff0c;是专门为装备制造行业设计的生产信息化管理系统。旨在实时监控装备制造生产流程&#xff0c;实现全流程的精细化管理和监控&#xff0c;提高生产效率、降低生产成本、提升产品质量。 本文将详细介绍装备制造行业MES的概念、技术及应用&#xff0c;…

七天速通javaSE:第四天 数组基础

文章目录 前言一、认识数组二、数组的声明和创建1. 声明数组变量2. 创建数组3. 变量的初始化&#xff08;赋值&#xff09;3.1 静态初始化3.2 动态初始化 3. 示例 三、数组的使用1. 循环1.1 普通for循环1.2 For-Each 循环 2. 数组作为函数的参数和返回值 前言 本文将为大家介绍…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十九)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 29 节&#xff09; P29《28.网络连接-第三方库axios》 要想使用第三方库axios&#xff0c;需要先安装ohpm&#xff0c;因为 axios…