C++:使自定义类支持迭代器
概述
在 C++ 中,链表迭代器是一种用来遍历链表(如 std::list)元素的工具。链表是一种数据结构,其中每个元素(节点)包含一个数据值和一个指向下一个节点的指针。链表迭代器允许以类似于数组的方式访问链表中的元素,但不需要直接操作指针。
链表迭代器的作用
访问元素:链表迭代器使你能够顺序访问链表中的每个元素,就像在数组中遍历元素一样。
遍历链表:通过迭代器,你可以在链表中前进或后退,从而进行遍历操作。这使得在链表中执行各种操作(如查找、修改、删除等)变得简单而直观。
抽象化操作:迭代器提供了一种统一的方式来访问不同类型的数据结构。无论是链表、数组还是其他容器,迭代器的使用方式大致相同,这让代码更加通用和易于维护。
使用示例
#include <iostream>
#include <list>
int main() {
std::list<int> myList = {1, 2, 3, 4, 5};
// 使用迭代器遍历链表
for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
std::cout << *it << " "; // 输出链表元素
}
return 0;
}
为什么要为自己的类设置迭代器?
参考下述链表类
class List {
public:
List(): head(new Node()) { }
~List();
bool push(int x, int y); // 在头部插入一个新坐标
bool pop(int x, int y); // 查找指定坐标,并删除
private:
Node* head;
};
在该链表中,定义了push
和pop
两个方法,现假定,我们需要能够从第一个节点开始,逐步在外部调用链表的每一个节点,有一种简单的实现方法:
- 定义
search(int i)
函数,从头开始,向后查询i
个节点 - 在外部采用for循环递增节点索引
i
。
这里给出一个伪代码:
for (int i = 0; i < 10; ++i) {
Node cur = myList.search(i);
std::cout << cur << std::endl;
}
上述方法能够实现在外部对链表节点的遍历,但是,当索引较大时,鉴于每一次都需要从头访问至索引处,算力开销极大,因此我们必须采用更高效的方法。
如何为类设置迭代器方法?
观察标准库中迭代器的使用方法:
for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
std::cout << *it << " "; // 输出链表元素
}
我们了解到需要实现如下内容:
- 定义迭代器类,包含一个
Node*
类型的指针cur
,指向当前元素。 - 在链表类中,定义
begin
、end
函数,分别指向第一个元素和尾节点。 - 定义
!=
运算符,以支持比较两个指针是否相同。 - 定义
++
运算符,使得可以更便携的遍历节点。 - 定义
*
运算符,使得可以采用指针方法访问到节点的值。
我们可以依次完成实现
class List {
public:
List() : head(new Node()) { }
~List();
bool push(int x, int y);
bool pop(int x, int y);
// 定义迭代器类
class Iterator {
public:
// 构造函数
Iterator(Node* node) : cur(node) {}
// 指针运算符
Cell& operator*() { return cur->cell; }
// 前置自增运算符
Iterator& operator++() {
if (cur) cur = cur->next;
return *this;
}
// 不等于运算符
bool operator!=(const Iterator& other) const { return cur != other.cur; }
private:
// cur字段
Node* cur;
}
// 分别定义begin()、end()方法
Iterator begin() const { return Iterator(head->next); }
Iterator end() const { return Iterator(nullptr); }
private:
Node* head;
};
完成上述实现后,我们就可以使用迭代器方法快捷的访问类成员了。
#include <iostream>
#include "list.h"
int main() {
List ROI;
// 插入节点
ROI.push(0, 0);
ROI.push(0, 1);
ROI.push(0, 2);
ROI.push(0, 3);
for (List::Iterator it = ROI.begin(); it != ROI.end(); ++it) {
std::cout << *it << "\n";
}
return 0;
}
C++:使自定义类支持迭代器的更多相关文章
- 自定义类支持foreach
建议使用yield语句简化迭代 using System; using System.Collections; namespace 自定义类实现foreach { class A { int[] w; ...
- 使自定义事件支持多绑定 js
<script language="JavaScript" type="text/javascript"> <!-- //定义类class1 ...
- [Yii2.0] 以Yii 2.0风格加载自定义类或命名空间 [配置使用Yii2 autoloader]
Yii 2.0最显著的特征之一就是引入了命名空间,因此对于自定义类的引入方式也同之前有所不同.这篇文章讨论一下如何利用Yii 2.0的自动加载机制,向系统中引入自定义类和命名空间.本文旨在抛砖引玉,如 ...
- 自定义类在PropertyGrid上的展示方法
自定义类在PropertyGrid上的展示方法 零.引言 PropertyGrid用来显示某一对象的属性,但是并不是所有的属性都能编辑,基本数据类型(int, double等)和.Net一些封装的类型 ...
- java学习--自定义类的实例的大小比较和排序
我们知道Object类有一个equals方法,用于比较两个对象是否相等 我们只要在自定义类中重写了equals方法(若不重写就是比较两个实例的地址,相当于==)就可以用来比较该类的两个实例是否相等 问 ...
- python面向对象反射-框架原理-动态导入-元类-自定义类-单例模式-项目的生命周期-05
反射 reflect 反射(reflect)其实是反省,自省的意思 反省:指的是一个对象应该具备可以检测.修改.增加自身属性的能力 反射:通过字符串获取对象或者类的属性,进行操作 设计框架时需要通过反 ...
- cocos2dx-3.x 导出自定义类到 lua 过程详解
转载请注明出处:http://www.cnblogs.com/Ray1024 一.简介 最近正在学习cocos2d中的lua游戏开发,因为lua开发的热更新特性,大家开发游戏好像都会优先选择lua作为 ...
- VBA中自定义类和事件的(伪)注册
想了解一下VBA中自定义类和事件,以及注册事件处理程序的方法. 折腾了大半天,觉得这样的方式实在称不上“注册”,所以加一个“伪”字.纯粹是瞎试,原理也还没有摸透.先留着,有时间再接着摸. 做以下尝试: ...
- Adobe Edge Animate –修改Edge Commons Spotlight功能,使之能支持播放中国网站视频
Adobe Edge Animate –修改Edge Commons Spotlight功能,使之能支持播放中国网站视频 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权 ...
- Extjs-4.2.1(二)——使用Ext.define自定义类
鸣谢:http://www.cnblogs.com/youring2/archive/2013/08/22/3274135.html --------------------------------- ...
随机推荐
- 探索Nuxt.js的useFetch:高效数据获取与处理指南
title: 探索Nuxt.js的useFetch:高效数据获取与处理指南 date: 2024/7/15 updated: 2024/7/15 author: cmdragon excerpt: 摘 ...
- iOS开发基础102-后台保活方案
iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间.然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即&qu ...
- PowerShell pnpm 报错
Vue3> pnpm run dev pnpm : 无法加载文件 D:\program files\nodejs\node_global\pnpm.ps1.未对文件 D:\program fil ...
- oeasy 教您玩转linux 之010208 满屏乱码 bb
我们来回顾一下 上一部分我们都讲了什么? 黑客帝国 各种速度颜色参数 最后我们想找一个让人完全崩溃的软件包,这不就来了,话不多说,先试试. apt show bbapt search bbsudo a ...
- [HTTP] HTTP 协议 Response Header 之 Content-Length、Transfer-Encoding与Content-Encoding
0 引言 在近期项目一场景中,一 Web API (响应内容:7MB - 40MB.数据项:5W-20W条)的网络传输耗时较大,短则 5s,长则高达25s,前端渲染又需要耗时 9s-60s. 在这个场 ...
- Java解压rar5兼容rar4
RAR文件格式由WinRAR开发,广泛用于文件压缩和归档.随着技术的发展,RAR5作为更新的版本,引入了多项改进以提高压缩效率和数据安全性. 压缩效率:RAR5通过增大字典大小至32MB,相较于RAR ...
- wandb原来是可以网络直连的,国内可以无障碍使用
一直不是很常使用神经网络训练可视化的工具,包括:tensorboard,等等,wandb平时也是直接就忽略,不过最近无意间看了看这个效果,感觉还是不错的,于是尝试了一下. 网上很多人说这个工具服务器在 ...
- Ubuntu22.04下vscode安装python代码格式化(Format Document)black模块及设置
相关: 如何在vscode中支持python的annotation(注解,type checking)--通过设置pylance参数实现python注解的type checking ubuntu22. ...
- Apache DolphinScheduler-3.2.0集群部署教程
集群部署方案(2 Master + 3 Worker) Apache DolphinScheduler官网:https://dolphinscheduler.apache.org/zh-cn Apac ...
- 你要的高效方案!基于Apache SeaTunnel快速集成SAP进入Redshift
摘要 本文深入探讨了Apache SeaTunnel及其商业版可视化数据同步平台WhaleTunnel在数据整合领域的应用,特别是如何高效地将SAP系统中的数据同步到Amazon Redshift.通 ...