在做Qt项目的时候,不要去用那些数组了,要用容器。用Qt专有的数据类型。QString和std::string是有区别的。
标准C++提供了两种字符串一种以\为结尾的字符数组即C风格字符串另外一种是std::string.
Qt提供了自己实现的 QString.功能更强大
QString 是由一系列Qchar组成的字符串.QString使用两个字节16 位表示一个字符。
使用的是UTF-16 双字节编码。 我们常见的编码比如UTF8.UTF8字符长度不固定导致字符串操作效率不高.
QtString 采用固定长度字符单元UTF16进行编码,字符串比较查询效率更高一些
QString采用的是UTF16,C++标准采用的是UTF8编码,Qt针对 C++标准字符串提供了QByteArray类来操作UTF8编码的本地字符串字节数组等。
QString的优势:
.append() 和 + 运算符用法和效果是一样的。
Qt容器提供动态数组数据结构跟std::vector类似性能,跟std::vector接近。
QVector基于动态数组,在内存中,QVector元素是连续存储的。
OVector适用于对访问速度要求较高的场景。
QVector内存分配采用预分配策略。向QVector添加元素的时候,如果内存不足,QVector会重新分配一块更大的内存并将原有的数据复制到新内存空间。
为了减少内存分配复制操作的开销,QVector通常会预留一定的额外空间,这就意味着QVector 实际容量大于当前存储数据的容量。
QVector删除元素时,通常不会立即释放内存,这样做是为了避免频繁的内存分配释放操作。
QVector的优点:随机访问、 连续存储、 自动扩容。
缺点: 插入删除性能差,预分配策略可能导致资源浪费,不支持节点存储,在频繁插入删除的场景下不如QLinkedList效率高。
QList 是 Qt 框架中的一个动态数组容器,它提供了对元素的高效操作,并支持动态增长和收
缩。
QList 的实现原理基于动态数组,但也包含了一些优化,使其适用于不同的应用场景。
数组结构:QList 内部使用数组 (或类似数组的结构)来存储素。元素在内存中是顺序存储
的,可以通过索引直接访问元素。
std::list是基于双向链表实现,内部元素分散存储。
动态增长:当添加元素导致数组空间不足时,QList 会动态分配更大的内存空间,并将原有元
素拷贝到新的内存空间中。这样,QList 在进行添加操作时能够保持高效性能。
动态收缩:当从列表中移除元素导致数组空闲空间过多时,QList 可能会缩小内存占用,释放
多余的内存。
快速插入和删除:在列表中间插入或删除元素时,QList 可以通过移动元素实现,而不是简单
地进行插入或删除操作。这样做的好处是减少了元素移动的次数,提高了性能。
优势:
随机访问速度快:由于元素是顺序存储的,QList 提供了常数时间的随机访问速度。
动态增长和收缩: QList 可以自动调整内存大小,适应不同的数据量,使其适用于动态变化的情况。
插入和删除效率较高: QList 在插入和删除操作时采用了一些优化策略,可以提供相对高效的性能。
劣势:
内存占用:由于 QList 是动态数组,可能会存在一些额外的内存占用,尤其是在数组空间动态
增长和收缩时。非线程安全: QList 不是线程安全的。在多线程环境中使用时,需要考虑同步机制。
使用建议:
对于小规模数据:当数据量较小时,QList 提供了方便的操作和较小的性能开销。对于大规模数据
当数据量较大时,考虑使用 QVector 或 QLinkedList,这些类在特定场景下可能提供更好的性能。
多线程环境:在多线程环境中,需要谨慎使用 QList,可以考虑使用 QReadWriteLock 或其他同步机制确保线程安全。
总体而言,QList 是一个通用的、易于使用的容器类,适用于许多应用场景。在选择容器类时,建议根据具体的需求和性能特征选择合适的容器。
QList nameList;
nameList<<"Jimmy"<<"Green"<<"Curry";
for(const QString& name: nameList)
{
qDebug()<<"name:"<::iterator it;
for(it=nameList.begin();it!=nameList.end();++it)
{
qDebug()<<"name:"<<*it;
}
QLinkedList 是 Qt 框架中提供的双向链表容器,用于存储和操作元素。
与 QList 不同,QLinkedList 使用链表而不是数组来组织元素。
实现原理:
双向链表结构: QLinkedList 内部使用双向链表来存储元素。每个节点包含一个数据元素以及指向前一个和后一个节点的指针节点
插入和删除:在链表中插入和删除节点的操作是高效的,不需要移动大量元素。这使得在链表中间插入或删除元素相对容易。
无需连续内存:由于链表的特性,QLinkedList 不要求元素在内存中是连续存储的,这在动态变化的场景中提供了更大的灵活性。
优势:
劣势:
使用建议:
QMap 和 QHash 都是 Qt 框架中提供的关联容器,用于存储键值对。它们在内部分别使用红黑树和哈希表来实现。下面是它们的主要区别:
QMap: 底层实现:
QHash: 底层实现:
共同点:关联容器:
使用建议:
哈希冲突:
注意,QHash 的性能依赖于哈希函数的质量,且可能存在哈希冲突的情况。在某些场景下,可能需要自定义哈希函数。
总体而言,选择使用 QMap 还是 QHash 取决于你的具体需求。如果对元素有序性要求较高,或者需要在遍历时按键的升序排列,可以选择 QMap 。如果对性能要求更高,并且不关心元素的有序性,可以选择 QHash 。
QMap 和 QMultiMap 都是 Qt 架中的关联容器,用于存储键值对。它们的主要区别在于处理键冲突的方式和存储多个相同键的能力。
QMap 对于相同的键,会覆盖旧值,保持每个键在容器中唯一。 QMultiMap 允许相同的键关联多个值。
如果每个键只与一个值相关联,可以使用 QMap。如果需要一个键与多个值关联,可以使用 QMultiMap。
QHash 和 QMultiHash 都是 Qt 架中的哈希表实现的关联容器,用于存储键值对。它们的主要区别在于处理键冲突的方式和存储多个相同键的能力。
QHash 对于相同的键,会覆盖旧值,保持每个键在容器中唯一。
QMultiHash 允许相同的键关联多个值。插入相同键的多个值会形成一个键的值列表。如果每个键只与一个值相关联,可以使用 QHash。
如果需要一个键与多个值关联,可以使用 QMultiHash 。
QSet 是 Qt 提供的用于存储不重复元素的无序集合。它是一个模板类,可以存储任意数据类型的元素。
QSet 的底层实现是基于哈希表(hash table) 的数据结构。哈希表是一种能够提供高效的插入、删除和查找操作的数据结构,它通过将元素映射到一个固定范围的桶 (buckets) 中来实现这些操作。
Qt 中没有 QMultiSet。在 Qt Ot 中,你可以使用 QList 或 QVector 来实现类似于允许重复元素的集合的效果。这两个容器类都允许相同的元素出现多次,并按照插入的顺序来维护这些元素。
(Red-BlackTree) 实现std::set 是 C++ 标准库中提供的一种有序集合容器,它基于红黑树红黑树是一种自平衡二叉搜索树,确保了树的深度在可接受范围内,从而保持了插入、删除和查找操作的高效性。
如果你项目写 Qt比较多,跟界面,业务相关的东西比较多,那么就可以选择使用 Qt 的容器。
如果你写的是一些跨平台的代码,比如你的代码要在iOS、Android上使用,同时要在 Qt 上使用,底层一些代码,比如网络通讯,FFmpeg, OpenGL 那么推荐使用 std 容器。
最好能够做到 Qt 上层界面,业务,跟下层数据层业务进行一个分离下层数据业务做到跨平台,可以在所有平台上跑iOS AndroidLinux macOS windows.
做Qt的最高境界其实是不使用Qt.最终都使用纯c++ 来做开发。