Qt 容器類 (QList、QVector、QLinkedList 等) 提供兩種迭代器風格:Java 風格 (易用) 與 STL 風格 (通用算法相容)。並透過隱式資料共享 (Copy-on-Write) 實現高效值傳遞語意。
迭代器不指向元素本身,而是指向「第一個元素之前」、「元素之間」、「最後一個元素之後」。
QListIterator<T>QList<double> list;
// ... 填充資料
QListIterator<double> i(list);
while (i.hasNext()) {
doSomethingWith(i.next());
}
// 反向遍歷
i.toBack();
while (i.hasPrevious()) {
doSomethingWith(i.previous());
}
QMutableListIterator<T>支援遍歷過程中插入、刪除、修改:
QMutableListIterator<double> i(list);
while (i.hasNext()) {
if (i.next() < 0.0)
i.remove(); // 安全刪除當前元素
}
每個容器提供 iterator (可修改) 與 const_iterator (唯讀)。begin() 指向首元素,end() 指向尾後位置 (如長度 5 的容器,end() 相當於 list[5])。
QList<double>::iterator i = list.begin();
while (i != list.end()) {
*i = qAbs(*i); // 解參考修改元素
++i;
}
若函式回傳容器值 (如 splitter->sizes()),必須先拷貝再迭代:
// 錯誤:每次迴圈重建臨時物件,迭代器失效
QList<int>::const_iterator i = splitter->sizes().begin();
// 正確:先拷貝
QList<int> list = splitter->sizes();
QList<int>::const_iterator i = list.begin();
Java 風格迭代器建構子內部自動處理拷貝,避免此問題。
Qt 容器與 QString、QImage、QPixmap 等類別採用引用計數機制:
at() 而非 []:[] 可作左值,編譯器無法判斷是否會修改,被迫分離;at() 唯讀,保證共享。const_iterator、constBegin()、constEnd():非 const 迭代器可能觸發分離。QVector<double> sineTable() {
QVector<double> vect(360);
for (int i = 0; i < 360; ++i)
vect[i] = std::sin(i / (2 * M_PI));
return vect; // 高效回傳,無深度複製
}
QVector<double> v = sineTable(); // 自然寫法,效能無虞
對比 STL 需透過參考參數輸出的笨重風格,Qt 隱式共享讓 C++ 也能享有 Java/動態語言般直觀的值語意。
QLinkedList<Movie> list;
Movie movie;
// ...
foreach (movie, list) {
if (movie.title() == "Citizen Kane") {
std::cout << "Found Citizen Kane" << std::endl;
break;
}
}
QPair<int, double> 時唯一合法寫法掌握兩種迭代器風格適用場景、避開 STL 迭代器臨時物件陷阱、善用 at()/const_iterator 釋放隱式共享效能,能寫出既優雅又高效的 Qt 容器操作程式碼。