STL-迭代器

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;//拷贝}--itSelf& 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;//拷贝}--itSelf& 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;//拷贝}--itSelf& 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;//拷贝}--itSelf& 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.mzph.cn/bicheng/36532.shtml

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

相关文章

背靠广汽、小马智行,如祺出行打得过滴滴和百度吗?

©自象限原创 作者丨艾AA 编辑丨薛黎 北京时间6月14日凌晨&#xff0c;在特斯拉股东大会上&#xff0c;马斯克阐述了对Robotaxi&#xff08;自动驾驶出租车&#xff09;商业模式的构想——特斯拉不仅会运营自己的无人驾驶出租车车队&#xff0c;还可以让特斯拉车主们的爱…

微服务开发 —— 项目环境搭建篇

环境搭建 Linux 环境搭建 Linux 环境搭建大家可以使用虚拟机 VMware、VirtualBox 等应用创建虚拟机&#xff0c;使用Vagrant也可以快捷搭建虚拟环境&#xff1b;Windows 中有 WSL2&#xff0c;Windows 中的 Docker 也对 WSL 进行了支持&#xff0c;也是一个不错的选择。或者可…

Windows - 像Linux一样使用alias

前言 阅读本文约2分钟 说明 使用doskey命令 设置别名 查看当前目录 doskey lldir 激活conda的spider环境 doskey spiderconda activate spider 退出conda环境 doskey condaqconda deactivate 查看所有别名 doskey /macros

实现设计开挂|如何设计出坚不可摧的网球拍?

数字揭秘 我们发现自己可能偶尔会以过激的方式表达沮丧或愤怒&#xff0c;哪怕是在公共场合。就算是世界级的网球运动员也无法避免偶尔的情绪爆发&#xff0c;他们有时会砸球拍来释放被压抑的情绪或应对来自竞赛的压力。 网球运动员的情绪爆发已被证明是不可避免的。哪怕是包括…

Linux系统相关函数总结

在应用程序当中&#xff0c;有时往往需要去获取到一些系统相关的信息&#xff0c;譬如时间、日期、以及其它一些系统相关信息&#xff0c;本章将向大家介绍如何通过 Linux 系统调用或 C 库函数获取这些系统信息。除此之外&#xff0c;还会向大家介绍 Linux 系统下的/proc 虚拟文…

浏览器插件利器-allWebPluginV2.0.0.14-beta版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX插件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持谷歌、火狐等浏…

js删除el-table删除新增项,有的已经保存有的未经保存

有时候在弹窗中的弹窗要删除数据,有的是刚新增进来的,没有经过保存就没有id,有的已经保存过就有id 根据情况设定是否为编辑模式,如果为编辑模式就需要进行筛选删除及接口,如果不是编辑模式,只需要进行筛选删除 this.editFlag true; // 为编辑模式// 删除伤亡名单handelDel() …

数据库管理系统(DBMS)

一.数据库管理系统 1.简介 数据库管理系统(Database Management System)是一种操纵和管理数据库的大型软件&#xff0c;用于建立、使用和维护数据库&#xff0c;简称DBMS。它对数据库进行统一的管理和控制&#xff0c;以保证数据库的安全性和完整性。用户通过DBMS访问数据库中…

【PWN · ret2libc | protobuf】[2024CISCN · 华中赛区]protoverflow

套了一层protobuf壳&#xff0c;然后就是简单的ret2libc 参考速递&#xff1a;深入二进制安全&#xff1a;全面解析Protobuf-CSDN博客 前言 第一次遇到protobuf&#xff0c;如果没有了解过&#xff0c;是显然做不出来的。此次复现&#xff0c;也算是点亮了一个技能点 一、什么…

如何用Vue3和Plotly.js实现一个动态3D图的在线展示

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 基于 Plotly.js 的交互式图表动画 应用场景 本代码演示了如何使用 Plotly.js 创建交互式图表动画&#xff0c;其中一个区域填充的区域在给定时间间隔内更新其数据。这种动画可用于可视化时间序列数据或展示数…

centOS7网络配置_NAT模式设置

第一步&#xff1a;查看电脑网卡 nat模式对应本地网卡的VMnet 8 &#xff0c;查看对应的IP地址。 第二步&#xff1a;虚拟网络编辑器 打开VMWare&#xff0c;编辑--虚拟网络编辑器&#xff0c;整个都默认设置好了&#xff0c;只需要查看对应的DHCP设置中对应的IP的起始&#…

算法金 | 没有思考过 Embedding,不足以谈 AI

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 抱个拳&#xff0c;送个礼 在当今的人工智能&#xff08;AI&#xff09;领域&#xff0c;Embedding 是一个不可或缺的概念。如果你没有…

Python学习笔记24:进阶篇(十三)常见标准库使用之数据压缩功能模块zlib,gzip,bz2,lzma的学习使用

前言 本文是根据python官方教程中标准库模块的介绍&#xff0c;自己查询资料并整理&#xff0c;编写代码示例做出的学习笔记。 根据模块知识&#xff0c;一次讲解单个或者多个模块的内容。 教程链接&#xff1a;https://docs.python.org/zh-cn/3/tutorial/index.html 数据压缩…

2024年度临沂市安全文化书画摄影展开幕

人海信息网山东讯 6月27日&#xff0c;2024年度临沂市安全文化书画摄影作品展&#xff0c;在临沂高新区隆重开幕。本次书画摄影展深入贯彻“以人为本&#xff0c;安全发展”的重要思想&#xff0c;立意高远&#xff0c;内涵丰富&#xff0c;思想深邃&#xff0c;承载着健康、幸…

List常用操作比for循环更优雅的写法

private String name; //姓名 private Integer age; //年龄 private Integer departId; //所属部门id } List list new ArrayList<>(); 复制代码 简单遍历 使用lamada表达式之前&#xff0c;如果需要遍历list时&#xff0c;一般使用增强for循环&#xff0c;代码如…

【AIGC】《AI-Generated Content (AIGC): A Survey》

文章目录 相关概念What is AI-generated content?Necessary conditions of AIGCHow can AI make the content better?The industrial chain of AIGCAdvantages of large-scale pre-trained modelsGeneration of smart textPros of AIGCCons of AIGCAIGC and Metaverse 挑战潜…

制作高校专属PPT时,如何将校徽设置成透明底色?无须PS

目录 示例&#xff1a;以清华大学为例 1必应搜索“清华大学校徽” 2保存清华大学校徽及校名。 3将校徽导入到PPT中 ​4 选中校徽&#xff0c;然后依次选择“图片格式”-->颜色-->设置透明色​编辑 5出现“画笔”&#xff0c;由于截图的缘故&#xff0c;画笔没有在截…

002关于Geogebra软件的介绍及与MatLab的区别

为什么要学Geogebra&#xff1f; 因为和MatLab的科学计算相比&#xff0c;GeoGebra重点突出教学展示&#xff0c;对于教师、学生人群来讲再合适不过了&#xff0c;尤其是可以融入到PPT里边呈现交互式动画&#xff0c;想想听众的表情&#xff01;这不就弥补了看到PPT播放数学公…

谷歌SEO在外贸推广中的应用效果如何?

谷歌SEO在外贸推广中非常有效。通过优化网站&#xff0c;可以提高在搜索结果中的排名&#xff0c;这意味着更多的潜在客户会看到你的产品和服务。 一个高排名的网站能带来更多自然流量&#xff0c;不需要花费广告费用。这种流量通常质量较高&#xff0c;因为用户是主动搜索相关…

[AIGC] Doris:一款高效的MPP数据仓库引擎

在大数据处理的领域中&#xff0c;Apache Doris&#xff08;原百度 Palo&#xff09;是一个高效的MPP&#xff08;大规模并行处理&#xff09;数据仓库&#xff0c;最初由百度开发&#xff0c;现在已经成为Apache的孵化项目。 (图片取自百度) – 文章目录 1. Doris的基础知识…