Qt容器类的对象模型及应用(线性结构篇)(好多图,比较清楚)
用Qt做过项目开发的人,肯定使用过诸如QList、QVector、QLinkList这样的模板容器类,它们虽然名字长的不同,但使用方法都大致相同, 因为其使用方法都大体相同,很多人可能随便拿一个容器类来使用,但却不知道这种选择是不是最优,这对于对性能要求不苛刻的应用,这种选择不会有任何影响,但是若性能要求苛刻的应用,无疑直接影响到你的系统的成败。上述提及的容器类本质上是对数据结构中的线性结构的不同的实现,本文通过介绍各容器类的实现原理,让我们知道什么时候该用什么样的容器,让大家不再感到迷茫。
1.QList的对象模型
一个QList 的对象模型如上图,ref表示该对象的引用计数,方便对对象释放,因为当通过append,insert等向对象添加项时,会通过new的方式从堆中分配内存来保存添加的项,若项数据不超过4个字节(即array中能存储下项数据),则最多只需new一次,如果有未存放项的array,则不需要new;若项数据超过4字节,因为array中存储不下超过4个字节的数据,所以至少要new一次,以存放数据项(如上图中的用户数据),当array中的所有项都已使用,这时需要再new一次,以增加array的空间大小,注意这里的array空间是连续的,所以重新分配空间后,需要将原来的空间的内容拷贝到新分配的空间中,并delete到原来的内存空间。上图中的 alloc表示分配的array的尺寸, array[begin]~array[end],表示使用的array,由此我们可以算出,QList的项个数,size() = end - begin + 1。
sharable表是该对象是否共享,在做对象拷贝的时候需要用到,比如有两个QList对象,list1 = list2;将list2赋值给list1,如果sharable为true,则仅将list2的对象指针直接赋值给list1的对象指针,这样的话,当我对list1操作时,实际上是对list2操作,因为两个对象都指向同一块内存,若sharable为false,则list1会首先分配一个和list2一样大小的内存,再把list2的内容拷贝到新分配的内存。
对于QList来说,sharable默认是false的,但对于接下来讲的QVector来说,sharable默认是true,所以QVector对象在做拷贝的时候,对象之间会共用同一个对象内存,这个要注意。
2.QVector的对象模型
QVector与QList的主要区别是QVector直接把要添加的数据项直接放到数组中,不管数据项有多大,它的空间是都是连续的,若数据项尺寸不超过1个指针长,QList与QVector没有什么区别,唯一的区别就是QList采用双向索引(begin和end),这样向前添加和向后添加项的时间复杂度是等同的。因为new操作是比较耗时的,使用QVector的resize事先分配若干空间,这样在append的时候,就不会再new空间了,也省去了空间拷贝的开销。
3.QLinkList的对象模型
QList、QVector是线性结构中的线性表结构,QLinkList的是线性结构中的链表结构,如上图,QLinkList的对象模型实际上是一个双向循环链表(图中循环没有画出来),红色色部分是链表头,包含有链表的尺寸,是否共享,及引用计数信息。对于每一次append操作,都会new出一个节点(图黑色部分)。
4.QVarLengthArray对象模型
5.由QList、QVector派生的对象
http://blog.csdn.net/rabinsong/article/details/9374213
Qt容器类的对象模型及应用(线性结构篇)(好多图,比较清楚)的更多相关文章
- Qt容器类的对象模型及应用(线性结构篇:对于QList来说,sharable默认是false的,但对于接下来讲的QVector来说,sharable默认是true)
用Qt做过项目开发的人,肯定使用过诸如QList.QVector.QLinkList这样的模板容器类,它们虽然名字长的不同,但使用方法都大致相同, 因为其使用方法都大体相同,很多人可能随便拿一个容器类 ...
- Qt——容器类(译)
注:本文是我对Qt官方文档的翻译,错误之处还请指正. 原文链接:Container Classes 介绍 Qt库提供了一套通用的基于模板的容器类,可以用这些类存储指定类型的项.比如,你需要一个大小可变 ...
- Qt容器类之一:Qt的容器类介绍
一.介绍 Qt库提供了一套通用的基于模板的容器类,可以用这些类存储指定类型的项.比如,你需要一个大小可变的QString的数组,则使用QVector<QString>. 这些容器类比STL ...
- Qt容器类汇总说明
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt容器类汇总说明 本文地址:http://techieliang.com/2017/ ...
- Qt容器类之二:迭代器
一.介绍 遍历一个容器可以使用迭代器(iterators)来完成,迭代器提供了一个统一的方法来访问容器中的项目.Qt的容器类提供了两种类型的迭代器:Java风格迭代器和STL风格迭代器.如果只是想按顺 ...
- Qt 中的对象模型(Object Model)
原标题:Qt 中的对象模型(Object Model)90不太后,余生皆折腾 本节内容主要讲了 Qt 对象模型比标准 C++ 对象模型多了什么内容,并介绍了组成 Qt 对象模型基础的相关的类.最后说明 ...
- Qt容器类之三:通用算法
在<QtAlgorithm>头文件中,Qt提供了一些全局的模板函数,这些函数是可以使用在容器上的十分常用的算法.我们可以在任何提供了STL风格迭代器的容器类上用这些算法,包括QList.Q ...
- Qt容器类——1. QList类、QLinkedList类和QVector类
在开发一个较高性能需求的应用程序时,程序员会比较关注这些容器类的运行效率,表2.1列出了QList.QLinkedList和QVector容器的时间复杂度比较. 1.QList类 QList<T ...
- Qt容器类(总结)(新发现的QQueue和QStack,注意全都是泛型)
Introduction Qt库提供了一组基于模板的一般化的容器类.这些容器可以存储指定的类型的元素.例如,如果你需要一个可变大小的Qstring数组,可以用QVector<QString> ...
随机推荐
- sass 语法实例
sass基本语法 1.定义一个变量,变量定义以$开头,以冒号分隔开. $blue:#1875e7; div{ color:$blue; } 编译之后的css代码: div { color: #1875 ...
- eclipse中删除多余的工作空间记录
所以对于不再使用的工作空间,每次出现在eclipse的“文件”>>“切换工作空间”里面的时候就觉得特别不爽. 所以认真研究了eclipse目录之后让我找到了,删除不需要工作空间记录的方法. ...
- jquery ajax 在ie7不能正常使用
jquery ajax结构不规范到时再ie8以下的用户不能正常使用.比如[1,2,].{1,2,},结构内部的最后不能有“,”.
- c# Linq及Lamda表达式应用经验之 GroupBy 分组
示例1: GroupBy 分组在List<>泛型中的应用 原表: 按姓名Nam 分组后结果: 对DATATABLE 进行LAMDA查询时必须在项目的引用中添加 System.Data.Da ...
- apache+mysql+php环境的手动搭建
一.搭建Apache Http Server 官方下载地址:http://www.apachehaus.com/cgi-bin/download.plx 搭建环境:win10 64位 WIN10 64 ...
- hibernate sql查询后对象转换成实体类
在多表查询的时候使用hibernate的sql查询的时候,一般返回的是object[]数组,或者可以使用 session.createSQLQuery(sql).setResultTransform ...
- R与数据分析旧笔记(十四) 动态聚类:K-means
动态聚类:K-means方法 动态聚类:K-means方法 算法 选择K个点作为初始质心 将每个点指派到最近的质心,形成K个簇(聚类) 重新计算每个簇的质心 重复2-3直至质心不发生变化 kmeans ...
- Enum基础
enum ColorE { RED, GREEN, BLUE; } public class GetEnumContent { public static void main(Stri ...
- poj1637 Sightseeing tour 混合图欧拉回路判定
传送门 第一次做这种题, 尽管ac了但是完全不知道为什么这么做. 题目就是给一些边, 有向边与无向边混合, 问你是否存在欧拉回路. 做法是先对每个点求入度和出度, 如果一条边是无向边, 就随便指定一个 ...
- 【转】linux Centos 6.5 安装桌面环境GNOME
在某种场合之下,我们使用的Linux还是要选择安装桌面环境的,所以在这里介绍一下如何给没有安装桌面环境的系统安装桌面环境. 以Centos 6.5 为例演示一下如何安装桌面环境. 一.首先查看系统的运 ...