您现在的位置是:主页 > 游戏攻略 >

qt下载Qt6现已发布!QList及相关类发生重大更改;文末附下载

2021-02-24 04:40:11 作者: 掌钛游侠网

在Qt 6中许多组件都将发生变化。容器也不例外。在这篇文章中,我将尝试对QList和相关类的最重要的更改进行说明。

QVector和QList统一

以前,Qt为这两个容器提供了非常不同的实现:QVector是一个自然而直接的类似于数组的容器,而QList在其实现中非常特殊,可以很好地容纳Qt自己定义和使用的类型。通过对Qt 6的现有类型进行更新,并以先前版本中已完成的操作为后盾,在类之间实现差异似乎几乎没有好处。此外,在许多情况下,QVector被证明是更好的选择。

因此,在Qt 6中,QVector和QList是统一的,并且QVector的模型用作基础实现。对于框架的高级用户而言,这意味着Qt 5 QList对于通用类型的额外间接访问级别已经消失,并且元素始终直接存储在分配的内存中。

但是,我们决定QList应该是带有实现的真实类,而QVector应该只是QList的别名。这样做的目的是:

由于许多Qt API使用QList而不是QVector简化了移植工作,我们相信用户代码也是如此,至少在与Qt交互的级别上是这样。弄清楚QVector2D和它的一些相关与QVector无关与QStringList和QByteArrayList命名约定同步快速预处理

在基于QVector的QList的新实现基础上,我们认识到一个重要的用例:在Qt 6之前,QList在开始时(即,前置)摊销了固定的固定插入时间。为了解决此属性,Qt 6中的QList也支持优化的前缀,并且为了使容器实现更加统一,QString和QByteArray也是如此。

不幸的是,一切都是有代价的。在本例中,代价是跨容器修改操作的迭代器有效性。与qt5中的QVector不同,qt6中的QList(因此也是QVector)允许较少的自由度来保持迭代器在操作之间有效。根据经验,任何向容器添加元素或从容器中移除元素的操作都会使"Remembered"迭代器失效,即使QList不是隐式共享的。qt6文档快照中可以找到该规则的更多细节和每个函数的异常,文档不断更新,以更好地反映当前的状态。

QList在删除元素时可能会收缩

通常,QList自动管理其内存。增长时,它会预先分配多余的内存以应对进一步的增长。对称地,我们希望QList在减小大小时减少占用的空间,尤其是当元素删除留下大量未使用的空间时。缩小到较小的容量可以减少内存占用,这在某些情况下是一个不错的选择。自Qt 5以来,此功能就是一项功能请求,但是,出于兼容性原因,由于用户依赖现有行为,因此我们无法更新代码。

默认情况下,这种内存管理机制很方便,也可能变得效率低下,例如,足够长的添加序列会导致重复的重新分配和额外的元素复制。同样,经常性清除会导致很多收缩。在这种情况下,增加和删除会产生不必要的成本。

QList :: reserve()是一种可用于减少重新分配频率并提示QList尽可能长时间保留现有内存容量的方法。将元素添加到QList时,预先预留(并因此分配)已知大小会导致对增长函数的后续调用(例如prepend,append,insert)归结为仅复制新数据。类似地,对reserve()的调用(例如,使用当前大小作为输入参数)将进行以下删除操作,以避免减少容量。

在某种程度上,reserve()允许干扰QList的内存管理。要恢复自动行为,应调用QList :: squeeze()。这样既可以根据存储的元素数精确地调整分配的空间,也可以提示QList您不再需要当前的存储容量来保持不变。但是请注意,如果您的数据寿命很短,则调用squeeze()(可能会重新分配内存)可能会非常昂贵。等待QList被销毁可能会更容易(更快速)。

QList的内存不受2GB限制

在Qt 6之前,QList被限制为最多使用2GiB的内存。如今,在64位体系结构中已经占据了主导地位,对于希望使用更多空间执行任务的用户而言,这是一个不必要的障碍。

在Qt 6中,更改了QList的基本大小类型以解决此问题,并且可以创建分配更大内存量的QList(当然,在系统提供的内存范围内)。因此,所有QList方法也都进行了更改以与此对齐,现在使用qsizetype而不是int。

不利的一面是,用户很可能会看到其编译器警告缩小转换范围。考虑以下示例。

在Qt5中完全正确的代码:

void myFunc(QList data) { int size = data.size(); // ... } ...由于从qsizetype到int的(变窄)转换,将在Qt 6中收到编译器警告。一个自然的解决方案是使用auto关键字而不是特定类型。当您要同时针对Qt 5和Qt 6进行构建时,这也是一种补救措施。

其他较小的变化

我们还简化了QStringList,它现在是QList的别名,而qt5版本中QStringList是从QList派生出来的一个不同的类。细心的读者可能会注意到,QStringList过去有QList中没有的特殊方法,例如QStringList::join()。这些QStringList特定的方法仍然可用,但是它们被烘焙到QList中,与QByteArrayList的方法类似。

您可能知道,QList实现利用了它元素类型的其他特性,它是通过使用Q_uDeclare\uTypeInfo()宏提供的。某些类型的特性允许使用更快的算法来提高“现成”性能。现在简化了这一机制:

现在,Q_MOVABLE_TYPE和Q_RELOCATABLE_TYPE的含义相同。由于C ++ 11引入了“可移动”的含义,该含义与Q_MOVABLE_TYPE的含义并不一致,因此我们鼓励客户端代码改用Q_RELOCATABLE_TYPE普通可复制和可破坏的类型不再需要标记为可重定位。它们将被自动检测到无论如何,如果对类型有疑问,您总是可以在编译时检查并确保特定的特征。例如:

static_assert(QTypeInfo::isRelocatable); // makes sure MyType is relocatable 如果这篇文章没能满足你的需求、点击“了解更多”,你讲获得两个好处:一是获得最新资讯以及教程以及安装包;二也是获得最新资讯以及教程以及安装包!

Tags: qt下载