常用Qt容器类
Qt提供了一系列容器类,类似于STL容器但更紧密集成到Qt框架中。常用容器包括:
-
顺序容器:
QList
- 最常用的动态数组QVector
- 类似QList,在Qt 5后与QList合并QLinkedList
- 双向链表QStack
- 后进先出堆栈QQueue
- 先进先出队列
-
关联容器:
QMap
- 键值对,按键排序QMultiMap
- 一键多值QHash
- 类似QMap但使用哈希表,查找更快QMultiHash
- 一键多值的哈希表QSet
- 无序集合
何时使用
- QList:大多数情况下默认选择,适合存储和访问元素
- QLinkedList:需要频繁在中间插入/删除时
- QMap/QHash :需要键值对存储时
- QMap:需要按键排序时
- QHash:需要更快查找且不关心顺序时
- QSet:需要快速判断元素是否存在时
关键点
- 隐式共享:Qt容器使用写时复制技术,提高性能
- 内存管理:存储指针时需注意所有权问题
- 迭代器:提供Java风格和STL风格两种迭代器
- 线程安全:多个线程读取是安全的,写入需要同步
简单Demo
cpp
#include <QCoreApplication>
#include <QDebug>
#include <QList>
#include <QMap>
#include <QSet>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 1. QList示例
QList<QString> fruits;
fruits << "Apple" << "Banana" << "Orange";
qDebug() << "Fruits:" << fruits;
// 遍历QList
qDebug() << "Iterating QList:";
for (const auto &fruit : fruits) {
qDebug() << fruit;
}
// 2. QMap示例
QMap<QString, int> inventory;
inventory["Apple"] = 10;
inventory["Banana"] = 5;
inventory["Orange"] = 8;
qDebug() << "\nInventory:";
for (auto it = inventory.begin(); it != inventory.end(); ++it) {
qDebug() << it.key() << ":" << it.value();
}
// 3. QSet示例
QSet<QString> fruitSet;
fruitSet << "Apple" << "Banana" << "Orange" << "Apple";
qDebug() << "\nUnique fruits:" << fruitSet;
// 4. 使用算法
qDebug() << "\nContains Banana?" << fruits.contains("Banana");
qDebug() << "Apple count in inventory:" << inventory.value("Apple");
return a.exec();
}
高级用法示例
cpp
// 存储指针时的内存管理
QList<QObject*> objectList;
QObject *obj1 = new QObject();
QObject *obj2 = new QObject();
objectList << obj1 << obj2;
// 使用范围for修改元素
QList<int> numbers = {1, 2, 3, 4, 5};
for (int &num : numbers) {
num *= 2;
}
qDebug() << "Doubled numbers:" << numbers;
// 使用STL算法
#include <algorithm>
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
qDebug() << "Sorted descending:" << numbers;
性能考虑
- QList对于存储指针类型非常高效
- QHash查找比QMap快,但消耗更多内存
- 频繁在中间插入/删除考虑QLinkedList
- 大量数据时考虑使用STL容器(如std::vector)
Qt容器与STL容器可以互相转换,根据具体需求选择合适的容器类型。