当前位置: 首页 > news >正文

C++设计模式_21_Iterator 迭代器(理解;面向对象的迭代器已过时;C++中使用泛型编程的方式实现)

Iterator 迭代器也是属于“数据结构”模式。GoF中面向对象的迭代器已经过时,C++中目前使用泛型编程的方式实现,其他语言还在使用面向对象的迭代器。

文章目录

  • 1. 动机(Motivation)
  • 2. 模式定义
  • 3. Iterator 迭代器代码分析
  • 4. 面向对象的迭代器与泛型编程实现的迭代器的对比
  • 5. 结构( Structure )
  • 6. 要点总结
  • 7. 其他参考

1. 动机(Motivation)

  • 在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为同一种算法在多种集合对象上进行操作”提供了可能。

不关心内部实现结构,一种算法可以应用到树形结构,也可以应用到链表、堆、栈的结构

  • 使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式。

2. 模式定义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露(稳定)该对象的内部表示。

----《设计模式》GoF

GoF中最早提出面向对象对象的方式实现迭代器,但是在讲面向对象的方式之前,需要重点说一下,这种方式在C++今天来讲已经过时了,因为学过STL泛型编程的都知道泛型编程中存在迭代器,思想与今天所讲的是一样的,都是通过一种接口的方式来隔离算法和容器之间的变化,但是GoF当初定义是面向对象的方式来定义的。

3. Iterator 迭代器代码分析

整体代码:

template<typename T>
class Iterator
{
public:virtual void first() = 0;virtual void next() = 0;virtual bool isDone() const = 0;virtual T& current() = 0;
};template<typename T>
class MyCollection{public:Iterator<T> GetIterator(){//...}};template<typename T>
class CollectionIterator : public Iterator<T>{MyCollection<T> mc;
public:CollectionIterator(const MyCollection<T> & c): mc(c){ }void first() override {}void next() override {}bool isDone() const override{}T& current() override{}
};void MyAlgorithm()
{MyCollection<int> mc;Iterator<int> iter= mc.GetIterator();for (iter.first(); !iter.isDone(); iter.next()){cout << iter.current() << endl;}}

代码分析:

首先来看GoF定义的代码,面向对象的方式

template<typename T>
class Iterator
{
public:virtual void first() = 0;virtual void next() = 0;virtual bool isDone() const = 0;virtual T& current() = 0;
};

first()提供第一个元素;next()是往下一个元素走;isDone() 代表到头了;T& current()是取你当前的一组;有些设计会将next()和T& current()合二为一。

template<typename T>
class MyCollection{public:Iterator<T> GetIterator(){//...}};

MyCollection是自己定义的集合,会返回一个属于我这个集合的迭代器

template<typename T>
class CollectionIterator : public Iterator<T>{MyCollection<T> mc;
public:CollectionIterator(const MyCollection<T> & c): mc(c){ }void first() override {}void next() override {}bool isDone() const override{}T& current() override{}
};

继承Iterator抽象类,对纯虚函数进行实现,一般实现的时候需要将集合传递进来CollectionIterator(const MyCollection<T> & c): mc(c){ }

到具体使用的时候

void MyAlgorithm()
{MyCollection<int> mc; //塞一个类型Iterator<int> iter= mc.GetIterator(); //拿到迭代器//进行遍历操作for (iter.first(); !iter.isDone(); iter.next()){cout << iter.current() << endl;}}

4. 面向对象的迭代器与泛型编程实现的迭代器的对比

当我们说到面向对象时,多态是其特征。像刚才说,这种面向对象的设计已经过时,就因为泛型编程,STL库在98年出来之后,大家一对比发现,面向对象的实现方式具有很多的缺点,具体来说最核心的缺点就出在面向对象上,面向对象的方式都是虚函数调用,虚函数都是有性能成本的,要绕虚表指针找到函数地址,需要二次指针的间接运算,每次都这样做,当进行遍历操作时,数据假如有10万个元素,这个循环造成的成本就差了很多。

    //进行遍历操作for (iter.first(); !iter.isDone(); iter.next()){cout << iter.current() << endl;}

98年之后的C++泛型编程中使用到的迭代器是使用模板来描述的,而模板也是一种多态技术,其实现的多态是编译式多态,即编译器在编译的时候会遍析具体的源代码,但是虚函数是运行时多态,运行时多态性能要低于编译时多态,因为编译时已经把工作做了,运行时直接调用源代码,不需要计算函数地址,因此以STL为标准的泛型编程广泛使用的是基于模板的多态迭代器,性能高于虚函数面向对象的迭代器。

而且第二个,泛型编程里有很多种迭代器,迭代器的接口发展出了更多的可能性,上面的写法只支持往前走(next()),不支持往回走(back()),我们知道泛型编程里迭代器可以++往前,--往后走,这些通过虚函数实现也可以,但是成本很高。模板的灵活性基于隐式约束,可以利用++、–操作符做为接口描述,面向对象只有虚函数一种。事实也证明,有了泛型编程的迭代器,大家再也不会用面向对象的迭代器。

但是上面所写的设计思路在其他语言,比如java,C#等得等到了极大的应用(基于运行时的多态),其他语言不支持编译时的模板体制。

5. 结构( Structure )

在这里插入图片描述

上图是《设计模式》GoF中定义的Iterator 迭代器的设计结构。结合上面的代码看图中对应关系如下图。

在这里插入图片描述

6. 要点总结

  • 迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。

  • 迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。

  • 迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。

7. 其他参考

C++设计模式——迭代器模式

相关文章:

C++设计模式_21_Iterator 迭代器(理解;面向对象的迭代器已过时;C++中使用泛型编程的方式实现)

Iterator 迭代器也是属于“数据结构”模式。GoF中面向对象的迭代器已经过时&#xff0c;C中目前使用泛型编程的方式实现&#xff0c;其他语言还在使用面向对象的迭代器。 文章目录 1. 动机(Motivation)2. 模式定义3. Iterator 迭代器代码分析4. 面向对象的迭代器与泛型编程实现…...

有一个 3*4 的矩阵,找出其中值最大的元素,及其行列号

1解题思路&#xff1a; 首先学会输入二维数组&#xff1b;然后知道如何比较求最大值&#xff1b;最后就是格式问题&#xff1b; 2代码&#xff1a; #include<stdio.h> int main() {int a[3][4];int i,j,max,row,line;for(i0;i<3;i){printf("请输入二维数组\n&…...

磁盘的命令

目录 1- 磁盘空间命令1.1 df1.2 du只想查看目录的权限 加 -d 参数 1- 磁盘空间命令 1.1 df 全称 disk free 快速获取磁盘被占用了多少空间, 目前还剩下所少空间 常用命令df -hdf 是从总体上统计系统各磁盘的占用情况,不能统计具体的文件夹或文件的大小 1.2 du 全称 disk u…...

一张图讲清楚业务稳定性要如何做:SRE体系化稳定性方案

概述&#xff1a;作为一个SRE、运维工程师&#xff0c;当我们在治理系统稳定性时&#xff0c;方法有很多&#xff0c;但往往无从下手。本文以一张逻辑图的形式&#xff0c;为读者提供治理稳定性的体系化思路。 先上图&#xff1a; 1、治理目标 我们做稳定性的目标&#xff0c…...

安卓端GB28181设备接入模块如何实现实时位置订阅(MobilePosition)

技术背景 实时位置&#xff08;MobilePosition&#xff09;订阅和上报&#xff0c;对GB28281设备接入终端尤其重要&#xff0c;如移动单兵设备、执法记录仪、智能安全帽、车载终端等&#xff0c;Android国标接入设备通过获取到实时经纬度信息&#xff0c;按照一定的间隔上报到…...

11.与JavaScript深入交流-[js一篇通]

文章目录 1.变量的使用1.1基本用法1.2理解 动态类型 2.基本数据类型2.1number 数字类型2.1.1数字进制表示2.1.2特殊的数字值 2.2string 字符串类型2.2.1基本规则2.2.2转义字符2.2.3求长度2.2.4字符串拼接 2.3boolean 布尔类型2.4undefined 未定义数据类型2.5null 空值类型 3.运…...

Ubuntu 搭建 DHCP ivp6 server 步骤

Ubuntu 搭建 DHCP ivp6 server 步骤 安装 DHCP server安装 radvd&#xff08;实现局域网路由功能)测试运行 安装 DHCP server apt 安装 isc-dhcp-server sudo apt-get install isc-dhcp-server修改配置文件 /etc/dhcp/dhcpd6.conf 内容如下&#xff1a; lease-time 7200; lo…...

分享大数据分析师前景怎么样? 从事行业有哪些?

数据分析师发展前景和待遇怎么样&#xff1f;有前途吗&#xff1f;好找工作吗&#xff1f;根据某招聘网数据显示&#xff0c;当前市场表现为&#xff1a; 2023年较2022年同期对比增长160%&#xff0c;2022年较2021年下降了46%。 工资待遇&#xff1a;2023年较2022年下降了2…...

通过wordpress能搭建有影响力的帮助中心

wordpress建站服务是一种提供简单易用的工具和功能&#xff0c;帮助用户轻松创建和管理网站的服务。它适用于各类网站管理员、个人博主和小型企业主&#xff0c;无论是想要搭建个人博客、展示作品集还是开设在线商店&#xff0c;都可以通过wordpress建站服务来实现。 | 一、搭建…...

word页脚设置,页脚显示第几页共有几页设置步骤

word页脚设置&#xff0c;页脚显示第几页共有几页设置步骤&#xff1a; 具体步骤&#xff1a; 步骤1&#xff1a; 步骤1.1选择页脚---空白页脚 步骤1.2&#xff0c;在"[在此处键入]"&#xff0c;直接输入你需要的格式&#xff0c;如 “第页/共页” 步骤1.3选择第“…...

C语言实现斐波那契数列的多种方法

斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;因数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为“兔子数列”。对于解决此类问题方法有四&#xff0c;前两…...

一文解决:Swagger API 未授权访问漏洞问题

Swagger 是一个用于设计、构建、文档化和使用 RESTful 风格的 Web 服务的开源软件框架。它通过提供一个交互式文档页面&#xff0c;让开发者可以更方便地查看和测试 API 接口。然而&#xff0c;在一些情况下&#xff0c;未经授权的访问可能会导致安全漏洞。本文将介绍如何解决 …...

Elasticsearch下载安装,IK分词器、Kibana下载安装使用,elasticsearch使用演示

首先给出自己使用版本的网盘链接&#xff1a;自己的版本7.17.14 链接&#xff1a;https://pan.baidu.com/s/1FSlI9jNf1KRP-OmZlCkEZw 提取码&#xff1a;1234 一般情况下 Elastic Search&#xff08;ES&#xff09; 并不单独使用&#xff0c;例如主流的技术组合 ELK&#xff08…...

springboot自定义404页面

添加配置类 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.servlet.Servlet; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.valves.ErrorReportValve; import org.apache.coyote.UpgradeProtoc…...

C/C++数据结构之时间复杂度和空间复杂度详细解析以及力扣刷题

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2.算法的…...

【需要理解】80 单词搜索

单词搜索 题解1 回溯&#xff08;需要改变起点&#xff09; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内…...

笔记本电脑的键盘鼠标如何共享控制另外一台电脑

环境&#xff1a; 联想E14 x2 Win10 across 2.0 问题描述&#xff1a; 笔记本电脑的键盘鼠标如何共享控制另外一台电脑 解决方案&#xff1a; 1.下载across软件&#xff0c;2台电脑都按装&#xff0c;一台设为服务端&#xff0c;一台客户端 2.把配对好设备拖到右边左侧…...

【计算机网络】(谢希仁第八版)第二章课后习题答案

第二章 1.物理层要解决哪些问题&#xff1f;物理层的主要特点是什么&#xff1f; 答&#xff1a;物理层要解决的主要问题&#xff1a; &#xff08;1&#xff09;物理层要尽可能地屏蔽掉物理设备和传输媒体&#xff0c;通信手段的不同&#xff0c;使数据链路层感觉不到这些差…...

笔记软件Notability mac中文版软件功能

Notability mac是一款帮助用户备注文件的得力工具&#xff0c;Notability Mac版可用于注释文稿、草拟想法、录制演讲、记录备注等。它将键入、手写、录音和照片结合在一起&#xff0c;便于您根据需要创建相应的备注。 Mac Notability mac中文版软件功能 将手写&#xff0c;照片…...

【C++的OpenCV】第十四课-OpenCV基础强化(三):Mat元素的访问之data和step属性

&#x1f389;&#x1f389;&#x1f389; 欢迎来到小白 p i a o 的学习空间&#xff01; \color{red}{欢迎来到小白piao的学习空间&#xff01;} 欢迎来到小白piao的学习空间&#xff01;&#x1f389;&#x1f389;&#x1f389; &#x1f496; C\Python所有的入门技术皆在 我…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

简单介绍C++中 string与wstring

在C中&#xff0c;string和wstring是两种用于处理不同字符编码的字符串类型&#xff0c;分别基于char和wchar_t字符类型。以下是它们的详细说明和对比&#xff1a; 1. 基础定义 string 类型&#xff1a;std::string 字符类型&#xff1a;char&#xff08;通常为8位&#xff09…...