用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派生的对象

https://blog.csdn.net/rabinsong/article/details/9374213

Qt容器类的对象模型及应用(线性结构篇:对于QList来说,sharable默认是false的,但对于接下来讲的QVector来说,sharable默认是true)的更多相关文章

  1. Qt容器类的对象模型及应用(线性结构篇)(好多图,比较清楚)

    用Qt做过项目开发的人,肯定使用过诸如QList.QVector.QLinkList这样的模板容器类,它们虽然名字长的不同,但使用方法都大致相同, 因为其使用方法都大体相同,很多人可能随便拿一个容器类 ...

  2. Qt——容器类(译)

    注:本文是我对Qt官方文档的翻译,错误之处还请指正. 原文链接:Container Classes 介绍 Qt库提供了一套通用的基于模板的容器类,可以用这些类存储指定类型的项.比如,你需要一个大小可变 ...

  3. Qt容器类之一:Qt的容器类介绍

    一.介绍 Qt库提供了一套通用的基于模板的容器类,可以用这些类存储指定类型的项.比如,你需要一个大小可变的QString的数组,则使用QVector<QString>. 这些容器类比STL ...

  4. Qt容器类汇总说明

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt容器类汇总说明     本文地址:http://techieliang.com/2017/ ...

  5. Qt容器类之二:迭代器

    一.介绍 遍历一个容器可以使用迭代器(iterators)来完成,迭代器提供了一个统一的方法来访问容器中的项目.Qt的容器类提供了两种类型的迭代器:Java风格迭代器和STL风格迭代器.如果只是想按顺 ...

  6. Qt 中的对象模型(Object Model)

    原标题:Qt 中的对象模型(Object Model)90不太后,余生皆折腾 本节内容主要讲了 Qt 对象模型比标准 C++ 对象模型多了什么内容,并介绍了组成 Qt 对象模型基础的相关的类.最后说明 ...

  7. Qt容器类之三:通用算法

    在<QtAlgorithm>头文件中,Qt提供了一些全局的模板函数,这些函数是可以使用在容器上的十分常用的算法.我们可以在任何提供了STL风格迭代器的容器类上用这些算法,包括QList.Q ...

  8. Qt容器类——1. QList类、QLinkedList类和QVector类

    在开发一个较高性能需求的应用程序时,程序员会比较关注这些容器类的运行效率,表2.1列出了QList.QLinkedList和QVector容器的时间复杂度比较. 1.QList类 QList<T ...

  9. Qt容器类(总结)(新发现的QQueue和QStack,注意全都是泛型)

    Introduction Qt库提供了一组基于模板的一般化的容器类.这些容器可以存储指定的类型的元素.例如,如果你需要一个可变大小的Qstring数组,可以用QVector<QString> ...

随机推荐

  1. Elasticsearch日志收集

    Install pip if necessary curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py&q ...

  2. C++中值传递(pass-by-value)和引用传递(pass-by-reference)

    1.pass-by-value的情况: 缺省情况C++以pass-by-value(继承C的方式)传递对象至(或来自)函数.函数参数都是以实际参数的复件为初值,调用端所获得的也是函数返回值的一个复件, ...

  3. Python关于super()函数的理解

    看下面的例子: class A: def __init__(self, name): self.name = name def bb(self): print('没事就爱瞎BB') class B(A ...

  4. B - Beautiful Year

    Problem description It seems like the year of 2013 came only yesterday. Do you know a curious fact? ...

  5. TreeSet中的排序问题——Comparable

    package com.etc.hashset; import java.util.HashSet; import java.util.Iterator; import java.util.Set; ...

  6. 使用NPOI实现简单的Excel导出功能

    [1]NPOI是啥? NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作. POI是一个开源的Java读写Excel. ...

  7. mac 下安装 mariadb

    通过brew 安装: brew install mariadb 初始化数据库 cd /usr/local/Cellar/mariadb/10.0.10/scripts mysql_install_db ...

  8. undefined reference to “boost” in Qt—Ubuntu

    一:使用PCL时遇到的问题 原因:缺少boost的lib包含: 在Pro文件里面添加: LIBS += -lboost_system .....................等库文件包含 二:编译B ...

  9. input左减右加

    <!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...

  10. Java中面向对象三大特性之——封装

    概述 面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改. 封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问.要访问该类的数据,必须通 ...