QT——QList的详细讲解
QList
是 Qt 框架中一个常用的模板类容器,用于存储和管理一组元素。它类似于 C++ 标准库中的 std::vector
,但针对 Qt 的使用场景进行了优化,特别是在内存布局和性能方面。
1. QList 的基本概念
1.1 QList 的特点
- 动态数组:
QList
是一个动态数组,可以动态调整大小。 - 高效随机访问:支持
[]
操作符快速访问元素(类似std::vector
)。 - 快速插入/删除:在列表头部和尾部插入/删除元素非常高效(
O(1)
时间复杂度)。 - 隐式共享(Copy-on-Write):多个
QList
可以共享相同的数据,只有在修改时才会复制数据,提高性能。 - 支持 Qt 的数据类型:可以直接存储
QString
、QVariant
、QObject*
等 Qt 类型。
1.2 QList 与 QVector 的区别
特性 | QList | QVector |
---|---|---|
内存布局 | 存储指针(间接访问) | 连续内存(直接访问) |
随机访问性能 | 稍慢(需要解引用) | 更快(直接访问) |
插入/删除性能 | 头部/尾部 O(1) ,中间 O(n) | 尾部 O(1) ,头部/中间 O(n) |
适用场景 | 频繁在头部插入/删除 | 频繁随机访问 |
推荐:
- 如果需要频繁在头部插入/删除,用
QList
。- 如果需要频繁随机访问,用
QVector
或std::vector
。
2. QList 的基本用法
2.1 创建 QList
#include <QList>
#include <QString>int main() {QList<int> intList; // 存储 intQList<QString> stringList; // 存储 QString// 初始化列表QList<int> numbers = {1, 2, 3, 4, 5};
}
2.2 添加元素
QList<QString> names;
names.append("Alice"); // 在尾部添加
names.prepend("Bob"); // 在头部添加
names.insert(1, "Charlie"); // 在索引 1 处插入// 也可以使用 << 运算符
names << "Dave" << "Eve";
2.3 访问元素
QList<int> numbers = {10, 20, 30, 40, 50};// 随机访问
int first = numbers.first(); // 10
int last = numbers.last(); // 50
int third = numbers.at(2); // 30(越界会检查)
int fourth = numbers[3]; // 40(不检查越界)// 遍历
for (int i = 0; i < numbers.size(); ++i) {qDebug() << numbers[i];
}// 范围遍历(C++11 风格)
for (int num : numbers) {qDebug() << num;
}
2.4 删除元素
QList<int> numbers = {1, 2, 3, 4, 5};numbers.removeFirst(); // 删除第一个元素(1)
numbers.removeLast(); // 删除最后一个元素(5)
numbers.removeAt(1); // 删除索引 1 的元素(3)
numbers.removeOne(4); // 删除第一个匹配的 4// 清空列表
numbers.clear();
2.5 查找元素
QList<QString> names = {"Alice", "Bob", "Charlie"};int index = names.indexOf("Bob"); // 返回 1
bool contains = names.contains("Dave"); // 返回 false
2.6 排序
QList<int> numbers = {3, 1, 4, 1, 5, 9};
std::sort(numbers.begin(), numbers.end()); // 升序排序
// 或使用 Qt 的排序
qSort(numbers.begin(), numbers.end()); // Qt5 及之前
3. QList 与 QVector 的选择
场景 | 推荐容器 |
---|---|
频繁在头部插入/删除 | QList |
频繁随机访问 | QVector |
存储小型对象(如 int 、指针) | QList (更高效) |
存储大型对象(如结构体) | QVector (连续内存更友好) |
4. 总结
特性 | 说明 |
---|---|
动态数组 | 可动态调整大小 |
高效头部操作 | prepend() 、removeFirst() 是 O(1) |
隐式共享 | 多个 QList 可以共享数据,减少复制开销 |
适用 Qt 类型 | 特别适合存储 QString 、QVariant 等 Qt 类型 |
与 STL 兼容 | 支持 begin() 、end() ,可与 <algorithm> 结合使用 |
QList
是 Qt 中最常用的容器之一,适合大多数动态数组场景。如果需要更高的随机访问性能,可以考虑 QVector
;如果需要频繁中间插入/删除,可以考虑 QLinkedList
。