005-Qt 的容器

auther: abinng date: 2026-03-19 14:28 createDate:2026-03-19 14:28

基本容器

Qt6 中大致分为两类容器:顺序容器、关联容器

注意没有链式容器,因为:

现代 CPU 的算力极快,但内存读取很慢。CPU 极其依赖连续内存带来的“预取(Prefetching)”红利。QList 这种指针跳跃式的内存布局,导致 Cache Miss 率极高,性能其实很差。

Qt6 中,QListQVector 合并了,根据官方手册,QVector 现在是 QList 的一个别名.

如果想用链式容器,还是使用 stl 中的 list 吧

顺序容器:QVector, QList, QStack, QQueue 关联容器:QMap, QMultiMap, QSet, QHash, QMultiHash

遍历方式

迭代器风格

1
2
3
begin(), end()
cbegin(), cend()
rbegin(), rend()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 1. 顺序容器 QList, QVector
QVector<int> vec = {1, 2, 3, 4, 5};
// 如果只是读取,务必使用 const_iterator 或 cbegin()/cend()
for (auto it = vec.cbegin(); it != vec.cend(); ++it) {
qDebug() << *it;
}
// 2. 关联容器,QMap, QHash
QMap<QString, int> res2;
res2.insert("a1", 10);
res2["w1"] = 30;
res2["b2"] = 20;
for (auto start = res2.cbegin(), end = res2.cend(); start != end; ++start) {
qDebug() << start.key() << ": " << start.value();
}

Range-based for 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
// 2. 关联容器,QMap, QHash
QMap<QString, int> res2;
res2.insert("a1", 10);
res2["w1"] = 30;
res2["b2"] = 20;
// 这个只能遍历他的 value
for (auto x : res2) {
qDebug() << x;
}
// 遍历key用这个
for (auto x : res2.keys()) {
qDebug() << x;
}

注意:

1
2
3
4
5
6
7
8
9
10
11
12
13
QVector<int> vec = getSomeVector();

// 陷阱:即使你写了 const auto &,只要 vec 本身不是 const 变量,
// range-based for 底层会调用非 const 的 begin(),这会触发 COW 深拷贝
for (const auto &item : vec) {
// ...
}

// 解法:使用 std::as_const() 强制转换为常量引用
// (在 Qt 5 中叫 qAsConst())
for (const auto &item : std::as_const(vec)) {
qDebug() << item;
}