最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt中foreach的實現(xiàn)示例

 更新時間:2026年02月02日 09:27:20   作者:上去我就QWER  
本文主要介紹了Qt中foreach的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

在 Qt 中,foreach 是一個 Qt 擴展的關鍵字(宏定義),用于遍歷容器類元素,語法簡潔、使用方便,底層基于容器的迭代器實現(xiàn),但屏蔽了迭代器的復雜操作,讓遍歷邏輯更直觀。它支持 Qt 容器(如 QList、QVectorQMap、QHash 等)和 STL 容器(如 std::vectorstd::list 等),是 Qt 開發(fā)中遍歷容器的常用方式。

一、核心本質:宏定義而非原生 C++ 語法

foreach 并非 C++ 標準關鍵字,而是 Qt 通過 #define 定義的宏,其底層映射到容器的迭代器遍歷邏輯。Qt 5 及以上版本默認啟用該宏,若需禁用(如避免與其他庫沖突),可在項目文件(.pro)中添加:

DEFINES += QT_NO_FOREACH

二、基本語法

1. 遍歷“值類型容器”(如 QList、QVector、std::vector)

語法:

foreach (const 元素類型 &變量名, 容器對象) {
    // 遍歷邏輯(變量名表示當前元素)
}
// 或(非 const,允許修改元素,僅適用于可修改的容器)
foreach (元素類型 &變量名, 容器對象) {
    // 修改元素的邏輯
}

示例:遍歷 QList

QList<QString> fruits = {"蘋果", "香蕉", "橙子"};

// 只讀遍歷(推薦用 const &,避免拷貝)
foreach (const QString &fruit, fruits) {
    qDebug() << fruit; // 輸出:"蘋果" "香蕉" "橙子"
}

// 可修改遍歷(需用非 const 引用,容器必須是可修改的)
foreach (QString &fruit, fruits) {
    fruit = "[水果]" + fruit; // 修改元素
}
qDebug() << fruits; // 輸出:["[水果]蘋果", "[水果]香蕉", "[水果]橙子"]

2. 遍歷“鍵值對容器”(如 QMap、QHash、std::map)

Qt 的鍵值對容器(QMap<K, V>QHash<K, V>)遍歷后,foreach 的“元素類型”是 QPair<K, V>(或 std::pair<K, V> 對于 STL 容器),通過 first 訪問鍵、second 訪問值。

語法:

foreach (const QPair<鍵類型, 值類型> &pair, 鍵值對容器) {
    qDebug() << "鍵:" << pair.first << ",值:" << pair.second;
}

示例:遍歷 QMap<int, QString>

QMap<int, QString> studentMap;
studentMap.insert(101, "張三");
studentMap.insert(102, "李四");
studentMap.insert(103, "王五");

// 遍歷鍵值對
foreach (const QPair<int, QString> &pair, studentMap) {
    qDebug() << "學號:" << pair.first << ",姓名:" << pair.second;
}
// 輸出(QMap 按鍵排序):
// 學號: 101 ,姓名: "張三"
// 學號: 102 ,姓名: "李四"
// 學號: 103 ,姓名: "王五"

3. 簡化寫法:使用auto(Qt 5.7+ 支持 C++11 及以上)

若不想顯式寫元素類型,可結合 auto 關鍵字(需開啟 C++11 支持,.pro 中添加 CONFIG += c++11):

QList<int> nums = {1, 2, 3, 4};
foreach (const auto &num, nums) {
    qDebug() << num; // 自動推導類型為 int
}

QHash<QString, int> scoreHash = {{"數(shù)學", 90}, {"語文", 85}};
foreach (const auto &pair, scoreHash) {
    qDebug() << pair.first << ":" << pair.second; // 自動推導為 QPair<QString, int>
}

三、關鍵特性與注意事項

1. 遍歷的是“容器的拷貝”(重要?。?/h3>

foreach 遍歷的是容器的 臨時拷貝,而非容器本身。這意味著:

  • 遍歷過程中修改容器(如添加/刪除元素),不會影響當前遍歷的結果(因為遍歷的是拷貝);
  • 若容器元素是“大對象”(如 QByteArray、自定義結構體),拷貝會帶來性能開銷,此時推薦用 迭代器 或 Qt 5.10+ 提供的 Q_FOREACH 替代(本質相同,但可通過 QT_USE_FOREACH_COPY 控制是否拷貝,默認仍拷貝)。

反例:遍歷中修改容器無效

QList<int> nums = {1, 2, 3};
foreach (const int &num, nums) {
    nums.append(num * 2); // 向原容器添加元素,但遍歷的是拷貝,不會遍歷到新元素
}
qDebug() << nums; // 輸出:[1,2,3,2,4,6](原容器被修改,但遍歷未包含新元素)

2. 支持“空容器”和“單元素容器”

foreach 會自動處理空容器(不執(zhí)行循環(huán)體),無需手動判斷容器是否為空:

QVector<QString> emptyVec;
foreach (const auto &str, emptyVec) {
    qDebug() << str; // 不會執(zhí)行
}

3. 與 Qt 容器的兼容性

foreach 完美支持所有 Qt 容器類:

  • 順序容器:QList、QVector、QByteArray、QStringList、QLinkedList;
  • 關聯(lián)容器:QMap、QMultiMap、QHash、QMultiHash;
  • 其他:QSet、QStack、QQueue(本質是順序容器的封裝)。

4. 與 STL 容器的兼容性

Qt 5.0+ 支持用 foreach 遍歷 STL 容器(如 std::vector、std::list、std::map),語法與 Qt 容器一致:

#include <vector>
#include <list>

std::vector<int> stlVec = {10, 20, 30};
foreach (const auto &val, stlVec) {
    qDebug() << val; // 輸出:10 20 30
}

std::map<std::string, int> stlMap = {{"a", 1}, {"b", 2}};
foreach (const auto &pair, stlMap) {
    qDebug() << QString::fromStdString(pair.first) << ":" << pair.second; // 輸出:"a":1 "b":2
}

5. 避免使用“容器的引用”作為遍歷對象

若誤將容器的引用傳給 foreach,會導致遍歷的是“引用的拷貝”,仍無法修改原容器,且語法冗余,不推薦:

QList<int> nums = {1,2,3};
// 不推薦:&nums 是引用,但 foreach 仍會拷貝引用指向的容器
foreach (const int &num, nums) { 
    // ...
}

6. 元素為“指針/智能指針”時的注意事項

若容器存儲的是指針(如 QList<QObject*>),foreach 遍歷的是指針的拷貝(而非對象的拷貝),此時修改指針指向的對象是有效的,但修改指針本身(如賦值為 nullptr)無效:

QList<QObject*> objList;
objList.append(new QObject);
objList.append(new QObject);

foreach (QObject *obj, objList) {
    obj->setObjectName("test"); // 有效:修改指針指向的對象的屬性
    obj = nullptr; // 無效:僅修改拷貝的指針,原容器中的指針不變
}

foreach (QObject *obj, objList) {
    qDebug() << obj->objectName(); // 輸出:"test" "test"
    delete obj;
}

四、foreach與迭代器、范圍 for 的對比

特性foreach(Qt 宏)迭代器(QList::iterator)范圍 for(C++11+)
語法簡潔性最高(無需手動控制迭代)中等(需初始化迭代器)高(原生語法,簡潔)
遍歷對象容器拷貝容器本身容器本身(可通過引用控制)
遍歷中修改容器無效(修改拷貝)有效(需注意迭代器失效)有效(需注意容器類型)
性能(大對象容器)較低(拷貝開銷)較高(無拷貝)較高(無拷貝)
兼容性Qt 容器 + STL 容器Qt 容器 + STL 容器Qt 容器 + STL 容器(C++11+)
適用場景簡單遍歷、無需修改容器復雜遍歷(如插入/刪除)現(xiàn)代 C++ 開發(fā)、追求原生語法

推薦選擇:

  • 簡單只讀遍歷(Qt 容器):優(yōu)先用 foreach(語法簡潔);
  • 遍歷中需修改容器/大對象容器:用迭代器或范圍 for;
  • 現(xiàn)代 C++ 項目(C++11+):推薦范圍 for(原生支持,無 Qt 依賴)。

五、常見錯誤與解決方案

錯誤 1:遍歷中修改容器,期望影響遍歷結果

原因foreach 遍歷的是拷貝,修改原容器不影響遍歷。
解決方案:改用迭代器或范圍 for:

QList<int> nums = {1,2,3};
// 用迭代器遍歷并修改
for (auto it = nums.begin(); it != nums.end(); ++it) {
    *it *= 2; // 直接修改原容器元素
}
qDebug() << nums; // 輸出:[2,4,6]

錯誤 2:遍歷大對象容器時性能低下

原因:拷貝大對象帶來開銷。
解決方案:用 const_iterator 或范圍 for(無拷貝):

// 大對象容器(如 QByteArray)
QList<QByteArray> bigList;
// ... 填充大量 QByteArray ...

// 用范圍 for 遍歷(無拷貝)
for (const auto &ba : bigList) {
    qDebug() << ba.size();
}

錯誤 3:混淆鍵值對容器的元素類型

原因QMap/QHash 的元素是 QPair,而非單獨的鍵或值。
解決方案:通過 pair.first(鍵)和 pair.second(值)訪問:

QHash<QString, int> scoreHash = {{"英語", 95}};
// 錯誤:元素類型是 QPair,不是 int
// foreach (const int &score, scoreHash) { ... }

// 正確:
foreach (const auto &pair, scoreHash) {
    qDebug() << pair.first << ":" << pair.second; // 英語:95
}

六、總結

foreach 是 Qt 提供的簡潔遍歷工具,核心優(yōu)勢是語法簡單、無需關注迭代器細節(jié),適合大多數(shù)“只讀、不修改容器”的場景。其底層基于容器拷貝,因此需注意:

  1. 遍歷中修改容器無效;
  2. 大對象容器慎用(拷貝開銷);
  3. 鍵值對容器需通過 QPair 訪問鍵和值。

若需復雜遍歷(如插入/刪除元素)或追求更高性能,建議使用迭代器或 C++11 范圍 for 循環(huán)。

到此這篇關于Qt中foreach的實現(xiàn)示例的文章就介紹到這了,更多相關Qt foreach內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Qt事件過濾器的實現(xiàn)示例

    Qt事件過濾器的實現(xiàn)示例

    本文介紹了Qt中的事件過濾器(Event Filter)機制,它是一種高效靈活的事件攔截處理方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-01-01
  • C/C++堆區(qū)專篇精講

    C/C++堆區(qū)專篇精講

    一直以來總是對這個問題的認識比較朦朧,我相信很多朋友也是這樣的,總是聽到內(nèi)存一會在棧上分配,一會又在堆上分配,那么它們之間到底是怎么的區(qū)別呢,讓我們一起來看看
    2022-10-10
  • C/C++?Qt?數(shù)據(jù)庫與TableView實現(xiàn)多組件聯(lián)動

    C/C++?Qt?數(shù)據(jù)庫與TableView實現(xiàn)多組件聯(lián)動

    Qt?數(shù)據(jù)庫組件與TableView組件實現(xiàn)聯(lián)動效果,本文通過案例給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-12-12
  • C語言調(diào)用go生成的動態(tài)庫的踩坑過程解析

    C語言調(diào)用go生成的動態(tài)庫的踩坑過程解析

    這篇文章主要為大家介紹了C語言調(diào)用go生成的動態(tài)庫的踩坑過程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Qt實現(xiàn)獲取文件大小與磁盤空間大小

    Qt實現(xiàn)獲取文件大小與磁盤空間大小

    這篇文章主要為大家詳細介紹了如何使用Qt實現(xiàn)獲取文件大小與磁盤空間大小,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-11-11
  • 基于Matlab制作一款簡單的龍舟小游戲

    基于Matlab制作一款簡單的龍舟小游戲

    這篇文章主要為大家介紹如何利用Matlab制作一款簡單的龍舟小游戲,文中的示例代碼講解詳細,對我們學習Matlab有一定幫助,需要的可以參考一下
    2022-03-03
  • VSCode配置Qt開發(fā)環(huán)境的步驟

    VSCode配置Qt開發(fā)環(huán)境的步驟

    本文詳細介紹了在VSCode中配置Qt開發(fā)環(huán)境的步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-09-09
  • C語言實現(xiàn)的排列組合問題的通用算法、解決方法

    C語言實現(xiàn)的排列組合問題的通用算法、解決方法

    這篇文章主要介紹了C語言實現(xiàn)的排列組合問題的通用算法、解決方法,本文使用C語言實現(xiàn)在程序中解決這個問題,需要的朋友可以參考下
    2014-08-08
  • C++設計模式之適配器模式

    C++設計模式之適配器模式

    這篇文章主要介紹了C++設計模式之適配器模式,本文詳細講解了C++中的適配器模式,并給出了實現(xiàn)代碼,需要的朋友可以參考下
    2014-09-09
  • 關于C++虛繼承的內(nèi)存模型問題

    關于C++虛繼承的內(nèi)存模型問題

    C++虛繼承的內(nèi)存模型是一個老生常談的話題,實現(xiàn)方法主要依賴于編譯器,本文從多個角度通過代碼詳解C++中虛繼承的內(nèi)存模型知識,感興趣的朋友跟隨小編一起看看吧
    2021-07-07

最新評論

苗栗市| 鹤岗市| 新源县| 乌海市| 贵州省| 石泉县| 湄潭县| 公安县| 邵武市| 兴隆县| 台中市| 武清区| 乾安县| 图们市| 郸城县| 霍邱县| 海丰县| 自治县| 阿鲁科尔沁旗| 太康县| 理塘县| 信丰县| 南通市| 呼玛县| 杨浦区| 裕民县| 同江市| 南丹县| 张北县| 富民县| 牡丹江市| 原阳县| 唐山市| 三明市| 始兴县| 工布江达县| 宁国市| 肥东县| 屏东市| 岑巩县| 霸州市|