Qt6 常用数据结构

Qt6 常用数据结构详解

Qt6 提供了丰富的数据结构类,这些类在 Qt 应用程序开发中广泛使用。本文将详细介绍 Qt6 中常用的数据结构,包括它们的特性、用法和最佳实践。

一、容器类 (Containers)

Qt6 提供了一套模板化的容器类,类似于 STL,但专为 Qt 设计,具有更好的集成性和性能。

1.1 顺序容器 (Sequence Containers)

1.1.1 QList

QList 是 Qt 中最常用的顺序容器之一,适用于大多数情况下的列表操作。

#include <QList>

QList<QString> names;
names << "Alice" << "Bob" << "Charlie";

// 访问元素
QString first = names.first();  // "Alice"
QString last = names.last();    // "Charlie"

// 添加元素
names.append("David");

// 插入元素
names.insert(1, "Eve");

// 删除元素
names.removeAt(2);  // 删除第三个元素

特点​​:

  • 内部实现为数组或链表,取决于大小
  • 随机访问效率高(O(1))
  • 插入和删除效率取决于位置(头部 O(1),中间/尾部 O(n))
1.1.2 QVector

QVector 类似于 std::vector,提供动态数组功能。

#include <QVector>

QVector<int> numbers;
numbers<< 1 << 2 << 3;

// 访问元素
int first = numbers.first();  // 1
int last = numbers.last();    // 3

// 添加元素
numbers.append(4);

// 插入元素
numbers.insert(1, 5);

// 删除元素
numbers.removeAt(2);  // 删除第三个元素

特点​​:

  • 连续内存存储
  • 随机访问效率高(O(1))
  • 插入和删除效率较低(O(n))
1.1.3 QLinkedList

QLinkedList 提供双向链表功能。

#include <QLinkedList>

QLinkedList<QString> names;
names << "Alice" << "Bob" << "Charlie";

// 访问元素(不如QList方便)
QString first = names.first();  // "Alice"
QString last = names.last();    // "Charlie"

// 添加元素
names.append("David");

// 插入元素
names.insert(names.begin() + 1, "Eve");

// 删除元素
names.removeOne("Bob");

特点​​:

  • 插入和删除效率高(O(1))
  • 随机访问效率低(O(n))
  • 内存不连续

1.2 关联容器 (Associative Containers)

1.2.1 QMap

QMap 提供键值对存储,按键排序。

#include <QMap>

QMap<QString, int> ageMap;
ageMap["Alice"] = 25;
ageMap["Bob"] = 30;
ageMap["Charlie"] = 35;

// 访问元素
int aliceAge = ageMap["Alice"];  // 25

// 遍历
for (auto it = ageMap.begin(); it != ageMap.end(); ++it) {
    qDebug() << it.key() << ":" << it.value();
}

// 查找
if (ageMap.contains("Bob")) {
    qDebug() << "Found Bob";
}

​特点​​:

  • 键值对存储
  • 自动按键排序
  • 查找效率高(O(log n))
1.2.2 QHash

QHash 类似于 QMap,但不保证顺序。

#include <QHash>

QHash<QString, int> ageHash;
ageHash["Alice"] = 25;
ageHash["Bob"] = 30;
ageHash["Charlie"] = 35;

// 访问元素
int aliceAge = ageHash["Alice"];  // 25

// 遍历
for (auto it = ageHash.begin(); it != ageHash.end(); ++it) {
    qDebug() << it.key() << ":" << it.value();
}

// 查找
if (ageHash.contains("Bob")) {
    qDebug() << "Found Bob";
}

特点​​:

  • 键值对存储
  • 不保证顺序
  • 查找效率通常比 QMap 高(O(1) 平均情况)
1.2.3 QSet

QSet 提供唯一元素的集合。

#include <QSet>

QSet<QString> names;
names << "Alice" << "Bob" << "Charlie";

// 添加元素
names.insert("David");

// 删除元素
names.remove("Bob");

// 检查存在
if (names.contains("Alice")) {
    qDebug() << "Found Alice";
}

// 遍历
for (const QString &name : names) {
    qDebug() << name;
}

特点​​:

  • 唯一元素集合
  • 不保证顺序
  • 查找效率高(O(1) 平均情况)

1.3 容器适配器

1.3.1 QStack

QStack 提供后进先出(LIFO)的栈结构。

#include <QStack>

QStack<int> stack;
stack.push(1);
stack.push(2);
stack.push(3);

// 访问栈顶元素
int top = stack.top();  // 3

// 弹出栈顶元素
stack.pop();  // 移除3

// 检查是否为空
if (stack.isEmpty()) {
    qDebug() << "Stack is empty";
} else {
    qDebug() << "Stack is not empty";
}

特点​​:

  • 后进先出(LIFO)
  • 基于 QVector 实现
1.3.2 QQueue

QQueue 提供先进先出(FIFO)的队列结构。

#include <QQueue>

QQueue<int> queue;
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);

// 访问队首元素
int front = queue.head();  // 1

// 出队
queue.dequeue();  // 移除1

// 检查是否为空
if (queue.isEmpty()) {
    qDebug() << "Queue is empty";
} else {
    qDebug() << "Queue is not empty";
}

​特点​​:

  • 先进先出(FIFO)
  • 基于 QList 实现

二、字符串类 (String Classes)

2.1 QString

QString 是 Qt 中处理 Unicode 字符串的主要类。

#include <QString>

QString str = "Hello, World!";

// 拼接字符串
str += " Welcome to Qt.";

// 子字符串
QString sub = str.mid(7, 5);  // "World"

// 查找子字符串
int pos = str.indexOf("Qt");  // 13

// 替换
str.replace("Qt", "C++");

// 转换大小写
QString upper = str.toUpper();  // "HELLO, WORLD! WELCOME TO C++."

特点​​:

  • Unicode 支持
  • 高效的内存管理
  • 丰富的字符串操作函数

2.2 QByteArray

QByteArray 用于处理原始字节数据。

#include <QByteArray>

QByteArray data = "Hello";

// 转换为十六进制
QString hex = data.toHex();  // "48656c6c6f"

// 追加数据
data.append(" World");

// 查找子字节序列
int pos = data.indexOf("World");  // 6

// 转换为整数
bool ok;
int num = data.left(3).toInt(&ok, 16);  // 如果data是"1a2",则num=418

特点​​:

  • 处理二进制数据
  • 高效的内存管理
  • 支持多种编码转换

三、日期和时间类 (Date and Time Classes)

3.1 QDate

QDate 表示公历日期。

#include <QDate>

QDate today = QDate::currentDate();
QDate specificDate(2023, 12, 25);

// 日期操作
QDate tomorrow = today.addDays(1);
QDate lastMonth = today.addMonths(-1);

// 格式化
QString formatted = today.toString("yyyy-MM-dd");  // "2023-11-15"

// 比较
if (today > specificDate) {
    qDebug() << "Today is after Dec 25, 2023";
} else {
    qDebug() << "Today is before or on Dec 25, 2023";
}

特点​​:

  • 公历日期表示
  • 丰富的日期操作函数
  • 支持多种日期格式

3.2 QTime

QTime 表示时间(小时、分钟、秒、毫秒)。

#include <QTime>

QTime now = QTime::currentTime();
QTime specificTime(14, 30, 0);  // 14:30:00

// 时间操作
QTime later = now.addSecs(3600);  // 加1小时
QTime earlier = now.addSecs(-1800);  // 减30分钟

// 格式化
QString formatted = now.toString("hh:mm:ss");  // "14:30:45"

// 比较
if (now > specificTime) {
    qDebug() << "Current time is after 14:30:00";
} else {
    qDebug() << "Current time is before or on 14:30:00";
}

特点​​:

  • 时间表示(小时、分钟、秒、毫秒)
  • 丰富的时间操作函数
  • 支持多种时间格式

3.3 QDateTime

QDateTime 结合 QDate 和 QTime 表示日期和时间。

#include <QDateTime>

QDateTime now = QDateTime::currentDateTime();
QDateTime specificDateTime(QDate(2023, 12, 25), QTime(14, 30, 0));

// 日期时间操作
QDateTime later = now.addSecs(3600);  // 加1小时
QDateTime earlier = now.addSecs(-1800);  // 减30分钟

// 格式化
QString formatted = now.toString("yyyy-MM-dd hh:mm:ss");  // "2023-11-15 14:30:45"

// 比较
if (now > specificDateTime) {
    qDebug() << "Current datetime is after Dec 25, 2023 14:30:00";
} else {
    qDebug() << "Current datetime is before or on Dec 25, 2023 14:30:00";
}

特点​​:

  • 结合日期和时间
  • 丰富的日期时间操作函数
  • 支持多种日期时间格式

四、文件和I/O类 (File and I/O Classes)

4.1 QFile

QFile 用于文件操作。

#include <QFile>
#include <QTextStream>

QFile file("example.txt");
if (file.open(QIODevice::ReadWrite | QIODevice::Text)) {
    QTextStream in(&file);
    QString content = in.readAll();
    file.seek(0);
    QTextStream out(&file);
    out << "New content\n" << content;
    file.close();
}

特点​​:

  • 文件读写操作
  • 支持多种打开模式
  • 与 QTextStream 结合使用方便文本处理

4.2 QTextStream

QTextStream 用于文本流处理。

#include <QTextStream>
#include <QString>

QString data = "Hello, World!";
QTextStream out(stdout);
out << data << Qt::endl;

QFile file("output.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    QTextStream stream(&file);
    stream << "Writing to file\n";
    file.close();
}

特点​​:

  • 文本流处理
  • 支持多种编码
  • 方便的格式化输出

4.3 QDataStream

QDataStream 用于二进制数据流处理。

#include <QDataStream>
#include <QFile>
#include <QString>

QFile file("data.bin");
if (file.open(QIODevice::WriteOnly)) {
    QDataStream out(&file);
    out << QString("Hello") << 42 << 3.14;
    file.close();
}

if (file.open(QIODevice::ReadOnly)) {
    QDataStream in(&file);
    QString str;
    int num;
    double pi;
    in >> str >> num >> pi;
    file.close();
    qDebug() << str << num << pi;  // "Hello" 42 3.14
}

特点​​:

  • 二进制数据流处理
  • 支持多种数据类型
  • 方便的序列化和反序列化

五、容器类的使用技巧

5.1 选择合适的容器

  • ​顺序访问频繁​​:使用 QVector 或 QList
  • ​键值对存储​​:使用 QMap 或 QHash
  • ​唯一元素集合​​:使用 QSet
  • ​栈结构​​:使用 QStack
  • ​队列结构​​:使用 QQueue

5.2 性能优化

  • ​预分配内存​​:对于已知大小的容器,使用 reserve() 预分配内存
  • ​避免不必要的拷贝​​:使用引用或指针传递大型对象
  • ​选择合适的数据结构​​:根据访问模式选择最合适的容器

5.3 安全使用

  • ​检查边界​​:在访问容器元素前,确保索引有效
  • ​处理空容器​​:在使用容器前,检查是否为空
  • ​线程安全​​:在多线程环境中,使用适当的同步机制

六、总结

Qt6 提供了丰富的数据结构类,涵盖了从基本容器到高级数据结构的各种需求。合理选择和使用这些数据结构,可以大大提高开发效率和程序性能。同时,掌握这些数据结构的使用技巧和最佳实践,对于编写高效、健壮的 Qt 应用程序至关重要。

通过本文的介绍,希望读者能够更好地理解和使用 Qt6 中的常用数据结构,从而在实际开发中得心应手。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_shenbing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值