qbytearry有数据上限吗_Qt6中QList和相关类都做了哪些更改?

在Qt6中,QList和QVector进行了统一,基于QVector的实现提供了优化,包括快速预处理和内存管理。QList在删除元素时可能收缩,可通过reserve()预先分配内存,而squeeze()恢复自动内存管理。此外,QList不再受2GB内存限制,但可能导致编译器警告。QStringList和QByteArrayList现在是QList的别名,特殊方法内置到QList中。
摘要由CSDN通过智能技术生成

Qt是一个跨平台框架,通常用作图形工具包,它不仅创建CLI应用程序中非常有用。而且它也可以在三种主要的台式机操作系统以及移动操作系统(如Symbian,Nokia Belle,Meego Harmattan,MeeGo或BB10)以及嵌入式设备,Android(Necessitas)和iOS的端口上运行。现在我们为你提供了免费的试用版。赶快点击下载Qt最新试用版吧>>

【Qtitan组件集】

QtitanRibbon

QtitanChart: 是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。并且支持所有主要的桌面操作系统。

QtitanDataGrid

在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(QListdata) { 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

标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,尊重他人劳动成果

1

好文不易,鼓励一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值