【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.pswp.cn/news/212261.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/212261.shtml
英文地址,請注明出處:http://en.pswp.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…

常用方法和調度

Thread類的方法 1、start()&#xff1a; ①啟動當前線程&#xff08;新的線程&#xff09; ②調用當前線程的run&#xff08; &#xff09;。 2. run()&#xff1a; ①通常須要進行重寫 ②將創建線程要執行的操作聲明在此方法中。 3.、currentThread()&#xff1a; ①靜態方法…

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

大家周末好&#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 跟…

【C++】多線程(三)

還是接著講多線程&#xff0c;照例&#xff0c;可以先看上一篇文章。 我們再次回顧一下上次編寫的使用async的多線程程序&#xff1a; int main() {async([]{ cout << "Maybe a new thread?" << endl; });cout << "Yeah, u r right!"…

力扣375周賽

力扣第375場周賽 統計已測試設備 差分數組優化 class Solution { public:int countTestedDevices(vector<int> &batteryPercentages) {int dec 0;for (int x : batteryPercentages) {dec x > dec;}return dec;} };雙模冪運算 快速冪模擬 class Solution { …