【Qt开发流程】之容器类2:使用STL风格迭代器进行遍历

概述

对于每个容器类,都有两种stl风格的迭代器类型:一种提供只读访问,另一种提供读写访问。应该尽可能使用只读迭代器,因为它们比读写迭代器快。
在这里插入图片描述
STL迭代器的API以数组中的指针为模型。例如,++操作符将迭代器推进到下一项,*操作符返回迭代器指向的项。实际上,对于QVector和QStack(它们将元素存储在相邻的内存位置),迭代器类型只是T *的一个typedef,而const_iterator类型只是const T *的一个typedef。

示例

在本文档中,将集中讨论QList和QMap。QLinkedList、QVector和QSet的迭代器类型与QList的迭代器具有完全相同的接口;类似地,QHash的迭代器类型与QMap的迭代器具有相同的接口。
下面是按顺序遍历QList<QString>中的所有元素并将它们转换为小写的示例:

  QList<QString> list;list << "A" << "B" << "C" << "D";QList<QString>::iterator i;for (i = list.begin(); i != list.end(); ++i)*i = (*i).toLower();

与java风格的迭代器不同,stl风格的迭代器直接指向项。容器的begin()函数返回一个迭代器,该迭代器指向容器中的第一项。容器的end()函数返回一个迭代器,指向容器中最后一项后面一个位置的虚项。End()标记一个无效的位置;它永远不能被取消引用。它通常用于循环的中断条件。如果列表为空,begin()等于end(),因此我们永远不会执行循环。
下图用红色箭头显示了包含四个元素的vector的有效迭代器位置:
在这里插入图片描述
使用stl风格的迭代器进行向后迭代可以使用反向迭代器完成:

  QList<QString> list;list << "A" << "B" << "C" << "D";QList<QString>::reverse_iterator i;for (i = list.rbegin(); i != list.rend(); ++i)*i = i->toLower();}

在到目前为止的代码片段中,使用一元*操作符检索存储在某个迭代器位置的项(QString类型),然后对其调用QString::toLower()。大多数c++编译器也允许编写i->toLower(),但有些编译器不允许。
对于只读访问,可以使用const_iteratorconstBegin()constEnd()。例如:

  QList<QString>::const_iterator i;for (i = list.constBegin(); i != list.constEnd(); ++i)qDebug() << *i;

stl风格API

下表总结了stl风格迭代器的API:

方法行为
*i返回当前项。
++i将迭代器推进到下一项
i += n将迭代器向前移动n个元素
–i将迭代器向后移动一项
i -= n将迭代器向后移动n个元素
i - j返回迭代器i和j之间的项数

++--操作符都可以作为前缀(++i--i)和后缀(i++i--)操作符使用。前缀版本修改迭代器并返回对修改后迭代器的引用;后缀版本在修改迭代器之前获取该迭代器的副本,并返回该副本。在忽略返回值的表达式中,我们建议您使用前缀操作符(++i--i),因为这些操作符略快一些。
对于非常量迭代器类型,一元*操作符的返回值可用于赋值操作符的左侧。
对于QMapQHash*操作符返回项的值组件。如果要检索键,请在迭代器上调用key()。为了对称,迭代器类型还提供了一个value()函数来检索值。例如,下面是将QMap中的所有项目打印到控制台:

  QMap<int, int> map;...QMap<int, int>::const_iterator i;for (i = map.constBegin(); i != map.constEnd(); ++i)qDebug() << i.key() << ':' << i.value();

由于隐式共享,函数为每个值返回一个容器的成本非常低。Qt API包含几十个函数,每个值返回一个QList或QStringList(例如,QSplitter::sizes())。如果希望使用STL迭代器遍历这些对象,则应该始终获取容器的一个副本,并遍历该副本。例如:

  // RIGHTconst QList<int> sizes = splitter->sizes();QList<int>::const_iterator i;for (i = sizes.begin(); i != sizes.end(); ++i)...// WRONGQList<int>::const_iterator i;for (i = splitter->sizes().begin();i != splitter->sizes().end(); ++i)...

对于返回const或非const对容器的引用的函数,不会出现此问题。

隐式共享迭代器问题

隐式共享对于stl风格的迭代器还有另一个后果:当迭代器在容器上处于活动状态时,应该避免复制容器。迭代器指向内部结构,如果复制容器,则应该非常小心地使用迭代器。例句:

  QVector<int> a, b;a.resize(100000); // make a big vector filled with 0.QVector<int>::iterator i = a.begin();// WRONG way of using the iterator i:b = a;/*Now we should be careful with iterator i since it will point to shared dataIf we do *i = 4 then we would change the shared instance (both vectors)The behavior differs from STL containers. Avoid doing such things in Qt.*/a[0] = 5;/*Container a is now detached from the shared data,and even though i was an iterator from the container a, it now works as an iterator in b.Here the situation is that (*i) == 0.*/b.clear(); // Now the iterator i is completely invalid.int j = *i; // Undefined behavior!/*The data from b (which i pointed to) is gone.This would be well-defined with STL containers (and (*i) == 5),but with QVector this is likely to crash.*/

上面的例子只显示了QVector的问题,但这个问题存在于所有隐式共享的Qt容器中。

结论

努力奔跑吧,反正没有一片属于你的风景

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

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

相关文章

Java开发工具:IDEA 2023.3(WinMac)中文激活版

IntelliJ IDEA 2023是一款由JetBrains公司出品的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为程序员设计。它以智能、高效和人性化为主要特点&#xff0c;致力于提高开发人员的生产力&#xff0c;帮助程序员更快、更好地编写代码。 在智能功能方面&#xff0c;Int…

Panalog 日志审计系统 sprog_deletevent.php SQL 注入漏洞复现

0x01 产品简介 Panalog大数据日志审计系统定位于将大数据产品应用于高校、 公安、 政企、 医疗、 金融、 能源等行业之中&#xff0c;针对网络流量的信息进行日志留存&#xff0c;可对用户上网行为进行审计&#xff0c;逐渐形成大数据采集、 大数据分析、 大数据整合的工作模式…

c语言一维数组总结详解

目录 介绍&#xff1a; 一维整型数组&#xff1a; 声明&#xff1a; 初始化&#xff1a; 打印输出&#xff1a; 输出结果&#xff1a; 浮点型数组&#xff1a; 代码&#xff1a; 运行结果&#xff1a; 补充&#xff1a; 一维字符数组&#xff1a; 字符数组声明及初始…

Python轴承故障诊断 (二)连续小波变换CWT

目录 前言 1 连续小波变换CWT原理介绍 1.1 CWT概述 1.2 CWT的原理和本质 2 基于Python的CWT实现与参数对比 2.1 代码示例 2.2 参数介绍和选择策略 2.2.1 尺度长度&#xff1a; 2.2.2 小波函数&#xff08;wavelet&#xff09;&#xff1a; 2.3 凯斯西储大学轴承数据的…

《算法与数据结构》答疑

答疑 问题一问题二问题三问题四 问题一 在匹配成功时&#xff0c;在返回子串位置那里&#xff0c;为什么不是i-t的长度啊&#xff0c;为什么还要加一 问题二 问题三 问题四 问&#xff1a;如果题目让我们构造一个哈夫曼树&#xff0c;像我发的这个例题的话&#xff0c;我画成我…

深度学习与计算机视觉技术的融合

深度学习与计算机视觉技术的融合 一、引言 随着人工智能技术的不断发展&#xff0c;深度学习已经成为了计算机视觉领域的重要支柱。计算机视觉技术能够从图像和视频中提取有用的信息&#xff0c;而深度学习则能够通过学习大量的数据来提高计算机视觉技术的性能。本文将探讨深…

贪心算法和动态规划

目录 一、简介 二、贪心算法案例&#xff1a;活动选择问题 1.原理介绍 三、动态规划案例&#xff1a;背包问题 1.原理介绍 四、贪心算法与动态规划的区别 五、总结 作者其他文章链接 正则表达式-CSDN博客 深入理解HashMap&#xff1a;Java中的键值对存储利器-CSDN博客…

Java Web——过滤器 监听器

目录 1. Filter & 过滤器 1.1. 过滤器概述 1.2. 过滤器的使用 1.3. 过滤器生命周期 1.4. 过滤器链的使用 1.5. 注解方式配置过滤器 2. Listener & 监听器 2.1. 监听器概述 2.2. Java Web的监听器 2.2.1. 常用监听器 2.2.1.1. ServletContextListener监听器 …

Course3-Week1-无监督学习

Course3-Week1-无监督学习 文章目录 Course3-Week1-无监督学习1. 欢迎1.1 Course3简介1.2 数学符号约定 2. K-means算法2.1 K-means算法的步骤2.2 代价函数2.3 选择聚类数量 3. 异常检测3.1 异常检测的直观理解3.2 高斯分布3.3 异常检测算法3.4 选取判断阈值 ε \varepsilon ε…

Redis 持久化 —— 超详细操作演示!

四、Redis 持久化 四、Redis 持久化4.1 持久化基本原理4.2 RDB持久化4.3 AOF持久化4.4 RDB与AOF对比4.5 持久化技术转型 五、Redis 主从集群六、Redis 分布式系统七、Redis 缓存八、Lua脚本详解九、分布式锁 数据库系列文章&#xff1a; 关系型数据库: MySQL —— 基础语法大全…

【京东服装推荐系统 - 数据爬取、可视化和个性化推荐】

京东服装推荐系统 - 数据爬取、可视化和个性化推荐 前言数据集与数据爬取数据分析与可视化Django搭建可视化平台主要功能1. 数据可视化2. 我的收藏3. 商品推荐4. 登录注册5. 信息展示6. 信息管理7. 对数据的收藏8. 推荐 创新点结语 前言 在现今的电商市场中&#xff0c;服装领…

鸿蒙原生应用/元服务开发-新版本端云一体化模板体验反馈

一、前言 云端一体化模板是基于Serverless服务构建的一套模板&#xff0c;提供了应用生态常见场景需求的代码实现&#xff0c;开发者可将所需能力快速部署和集成到自己的应用中。 二、准备 体验最新的远端一体化模板&#xff0c;需要将云模板替换掉。为此&#xff0c;我们需要做…

我对迁移学习的一点理解——领域适应(系列3)

文章目录 1. 领域适应&#xff08;Domain Adaptation&#xff09;的基本概念2.领域适应&#xff08;Domain Adaptation&#xff09;的目标3.领域适应&#xff08;Domain Adaptation&#xff09;的实现方法4.领域适应&#xff08;Domain Adaptation&#xff09;的可以解决的问题…

gittee使用教学

一、git简介 Git是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效的处理任何大小项目的版本管理。 核心功能&#xff1a; 项目的版本管理 团队协同开发 二、准备工作 1、下载 Git 2、除了选择安装位置以外&#xff0c;其他都无脑安装 3、检查一下安装情况 win…

这嵌入式“玩具”也太酷了吧~

大家周末好&#xff0c;我是bug菌&#xff5e; 今天看到有朋友晒出了一个“玩具”&#xff0c;实在是太酷了&#xff0c;嵌入式开发人员谁不爱&#xff1f;于是去了解了下&#xff0c;顺便分享给大家&#xff5e; 这机器是clockwork推出的uconsole,console大家这应该很熟悉&…

Leetcode刷题笔记题解(C++):92. 反转链表 II

思路&#xff1a;获取要反转的区间&#xff0c;拆开之后进行反转再拼接 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* …

【Linux】stat命令使用

stat命令 stat命令用于显示文件的状态信息。stat命令的输出信息比ls命令的输出信息要更详细。 著者 由Michael Meskes撰写。 stat命令 -Linux手册页 语法 stat [文件或目录] 命令选项及作用 执行令 &#xff1a; stat --help 执行命令结果 参数 -L、 --dereference 跟…

Star CCM+ 停止并保存用命令行运行的计算

在 StarCCM 命令行运行 中介绍了命令行运行计算的方法&#xff0c;有网友询问停止计算的命令&#xff0c;但计算一旦提交之后应该是不能用命令结束的&#xff0c;除非是用 kill 或任务管理器直接结束进程。然而&#xff0c;直接结束进程不会自动保存计算结果。 问题 通常情况下…

lv12 系统移植导学 1

1 导学 Kernel学习主要包括三块内容&#xff0c;ARM&#xff08;汇编、协议&#xff09;、系统移植、驱动移植 lv12主要时安装系统linux linux主要帮我们实现了5大功能 1 进程、线程管理 2 内存管理 3 网络协议栈管理 4 文件系统管理 5 设备管理 2 移植的目的 不同架构…

【数据结构】——排序篇(下)

前言&#xff1a;前面我们的排序已经详细的讲解了一系列的方法&#xff0c;那么我们现在久之后一个归并排序了&#xff0c;所以我们现在就来讲解一下归并排序。 归并排序&#xff1a; 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法…