简介
- Qt 中常见的数据类型及其笔记
Qt QAtomicInt类型 详解
QAtomicInt
是 Qt 中提供的一种用于原子操作的整数类型。原子操作指的是在多线程环境中执行的操作,它们在 CPU 层级上是不可分割的,确保操作在执行时不会被中断,从而避免线程竞争问题。
QAtomicInt
概述
QAtomicInt
是一个提供了基本整型(int
)的原子操作封装的类。它通常用于实现线程安全的计数器或其他需要原子性递增、递减操作的场景。
特性
- 原子性:所有的操作都在底层以原子方式执行,避免了线程安全问题。
- 跨平台支持:Qt 提供的原子操作在不同的平台上具有一致性,可以在 Windows、Linux、macOS 等平台上使用。
主要方法
以下是 QAtomicInt
常用的方法:
构造函数
QAtomicInt()
:默认构造一个原子整数,并将其初始化为 0。QAtomicInt(int value)
:使用指定的值初始化原子整数。
读操作
int loadAcquire() const
:获取当前值,确保所有读操作在此操作之前完成。int loadRelaxed() const
:获取当前值,但不强制同步内存。
写操作
void storeRelease(int newValue)
:设置新值,确保所有写操作在此操作之后完成。void storeRelaxed(int newValue)
:设置新值,但不强制同步内存。
增减操作
bool ref()
:将值递增 1。如果结果是非零值,返回true
,否则返回false
。bool deref()
:将值递减 1。如果结果是非零值,返回true
,否则返回false
。int fetchAndAddAcquire(int value)
:在获取值后再增加指定的值。int fetchAndAddRelaxed(int value)
:在不强制同步内存的情况下增加指定的值。int fetchAndStoreAcquire(int newValue)
:获取当前值并将其设置为newValue
。int fetchAndStoreRelaxed(int newValue)
:在不强制同步内存的情况下设置新值。
使用场景
- 线程计数器:在多线程应用中,可以使用
QAtomicInt
来实现一个线程安全的计数器。 - 资源管理:可以用于引用计数的实现,确保在多线程环境下资源能够正确地分配和释放。
示例代码
以下是一个使用 QAtomicInt
的简单例子:
1 |
|
在这个例子中,我们创建了两个线程,每个线程都递增 counter
1000 次。由于使用了 QAtomicInt
,计数操作是线程安全的,因此最终的计数值是 2000。
注意事项
QAtomicInt
适合用于简单的整数原子操作。如果需要更复杂的原子操作,可以考虑使用QAtomicInteger<T>
或QMutex
、QSemaphore
等同步原语。
QAtomicInt
提供了一种简单而高效的方式来处理多线程环境中的整数操作,确保数据的一致性和线程安全性。
Qt QString 详解
QString
是 Qt 框架中用于表示和操作文本字符串的类。它是一个 Unicode 字符串类,能够很好地处理多语言字符集和复杂文本操作。QString
提供了丰富的功能用于创建、修改、查询和转换字符串。以下是 QString
的详细介绍,包括常用功能和示例代码。
1. QString 基本概念
QString
是一个 Unicode 字符串类,支持宽字符集。Qt 使用 UTF-16 编码存储字符串。相比 C++ 的 std::string
,QString
更加适合处理包含多语言和特殊字符的文本。
2. QString 的构造方法
QString
提供了多种构造函数,可以从各种数据类型构建字符串。
1 | QString str1; // 空字符串 |
3. 常用方法
3.1. 字符串拼接
QString
提供了多种方式来拼接字符串。
使用
+
运算符拼接:1
2
3QString str1 = "Hello";
QString str2 = "World";
QString result = str1 + " " + str2; // "Hello World"使用
append()
方法拼接:1
2QString str = "Hello";
str.append(" World"); // "Hello World"
3.2. 字符串长度和访问
获取字符串长度:
1
2QString str = "Hello";
int length = str.length(); // 5访问单个字符:
1
QChar ch = str.at(1); // 'e'
3.3. 查找和替换
QString
提供了多种查找和替换子字符串的函数:
查找子字符串:
1
2QString str = "Hello, Qt!";
int index = str.indexOf("Qt"); // 返回子字符串首次出现的索引,结果是 7替换子字符串:
1
2QString str = "Hello, World!";
str.replace("World", "Qt"); // 结果是 "Hello, Qt!"
3.4. 大小写转换
- 转换为大写或小写:
1
2
3QString str = "Hello";
QString upperStr = str.toUpper(); // "HELLO"
QString lowerStr = str.toLower(); // "hello"
3.5. 截取字符串
使用
mid()
截取部分字符串:1
2QString str = "Hello, Qt!";
QString substr = str.mid(7, 2); // 结果是 "Qt"使用
left()
和right()
:1
2QString leftStr = str.left(5); // "Hello"
QString rightStr = str.right(3); // "Qt!"
3.6. 字符串分割
- 使用
split()
按照分隔符拆分字符串:1
2QString str = "apple,banana,grape";
QStringList list = str.split(","); // 拆分为 ["apple", "banana", "grape"]
3.7. 转换为其他数据类型
转换为整数、浮点数等:
1
2
3
4
5QString str = "123";
int num = str.toInt(); // 123
QString floatStr = "123.45";
double num2 = floatStr.toDouble(); // 123.45转换为字节数组:
1
2QString str = "Hello";
QByteArray byteArray = str.toUtf8(); // UTF-8 编码的字节数组
4. 静态方法
4.1. 创建字符串
使用
QString::number()
方法从数值创建字符串:1
2QString str = QString::number(42); // "42"
QString str2 = QString::number(3.1415); // "3.1415"使用
arg()
格式化字符串:1
QString str = QString("The value is %1").arg(42); // "The value is 42"
5. 比较字符串
使用
compare()
方法比较两个字符串:1
2
3QString str1 = "apple";
QString str2 = "orange";
int result = QString::compare(str1, str2); // < 0,因为 "apple" 在字典序中小于 "orange"也可以使用
==
或!=
比较字符串:1
2
3if (str1 == str2) {
// 字符串相等
}
6. 字符串的编码处理
QString
内部使用 UTF-16 存储字符,但可以轻松转换为其他编码格式,例如 UTF-8、Latin1 等。
1 | QString str = "你好,世界"; |
7. 性能优化
QString
使用了引用计数(copy-on-write)的机制来优化性能,避免不必要的拷贝操作。当多个 QString
对象引用同一数据时,它们共享数据;只有当其中一个发生修改时,才会执行深拷贝。
8. 使用 QString
与 QByteArray
的转换
QByteArray
是字节数组类,而 QString
是 Unicode 字符串类,它们可以互相转换。
1 | QString str = "Hello"; |
9. 处理空字符串
isEmpty()
和isNull()
用于判断字符串是否为空或为null
:1
2
3QString str;
bool empty = str.isEmpty(); // true,因为是空字符串
bool null = str.isNull(); // true,因为没有分配任何值
10. 总结
QString
是一个功能强大的类,能够处理各种复杂的字符串操作。它的 Unicode 支持使其在处理多语言字符时特别有效,且提供了高效的性能优化措施。
Qt QVector 详解
QVector
是 Qt 框架中用于存储相同类型元素的动态数组类,类似于 C++ 标准库的 std::vector
。它提供了许多方便的接口来进行动态分配、访问和操作数据。下面是对 QVector
的详解。
1. 基本概念
QVector<T>
是一个模板类,T
是其中元素的类型。QVector
可以根据需要动态调整数组的大小,支持类似数组的下标访问方式,并且性能表现与 std::vector
类似。
1 | QVector<int> intVector; // 创建一个存储整数的 QVector |
2. 常用操作
2.1 初始化
QVector
支持多种初始化方式,包括默认构造、指定大小的构造、和使用初始值的构造等。
1 | QVector<int> vec1; // 默认构造,空向量 |
2.2 访问元素
可以通过下标访问或者使用 at()
函数。
1 | int first = vec3[0]; // 使用下标访问 |
2.3 添加元素
可以通过 append()
和 push_back()
方法向向量末尾添加元素。insert()
方法可以在特定位置插入元素。
1 | vec1.append(3); // 向尾部添加元素 |
2.4 删除元素
可以使用 remove()
, removeAt()
, removeFirst()
, removeLast()
等函数来删除元素。
1 | vec1.removeAt(0); // 删除索引为 0 的元素 |
2.5 查找和判断
QVector
提供 contains()
来判断是否包含某元素,indexOf()
和 lastIndexOf()
用于查找某个元素的索引。
1 | bool hasValue = vec1.contains(5); // 判断是否包含 5 |
2.6 大小和容量
QVector
动态调整大小,可以通过 size()
获取当前元素的数量,通过 capacity()
获取预分配的内存容量。可以通过 resize()
改变 QVector
的大小。
1 | int size = vec1.size(); // 获取当前元素数量 |
3. 迭代
支持 C++ 范围循环(range-based for loop)和迭代器。
1 | for (int value : vec1) { |
4. 性能
- 内存管理:
QVector
会动态调整内存,避免频繁的内存分配。通常,capacity()
比size()
大,以减少内存重新分配的次数。 - 浅拷贝优化(Copy-on-Write):
QVector
使用 Qt 的隐式共享机制,也称为浅拷贝。当一个QVector
被复制时,实际上并不会立即进行数据复制,直到修改操作发生,这提高了性能。
5. 与其他容器的互操作
QVector
提供了与其他容器(如 QList
, QSet
)的互操作能力,可以方便地将 QVector
转换为其他容器类型。
1 | QList<int> list = vec1.toList(); // 将 QVector 转为 QList |
6. 常用函数总结
append(T value)
/push_back(T value)
:在末尾添加元素。at(int i)
:返回指定索引处的元素。size()
:返回当前元素数量。capacity()
:返回当前预分配的内存大小。clear()
:清空所有元素。contains(T value)
:判断是否包含某个元素。indexOf(T value)
:返回某个元素的索引。removeAt(int i)
:删除指定位置的元素。resize(int size)
:调整大小。
7. QVector 使用示例
下面是一个简单的示例,演示了 QVector
的基本用法。
1 |
|
总结
QVector
是 Qt 提供的强大而灵活的动态数组容器,适用于需要高效存储和访问大量相同类型数据的场景。在日常使用中,可以充分利用其丰富的 API 和高性能特性来简化开发流程。