Qt扫盲-QVector理论总结

news2024/12/29 8:46:48

QVector理论总结

  • 一、概述
  • 二、使用
    • 1. 声明初始化
    • 2. 获取元素和链表信息
    • 3. 常用操作
    • 4. 迭代Vector
  • 三、注意

一、概述

QVector是Qt的泛型容器类之一。它将每一个元素存储在相邻的内存位置,并提供快速的基于索引的访问
QList, QLinkedList, QVector, QVarLengthArray提供类似的api和功能。它们通常是可互换的,但会对性能造成影响。

QVector应该是默认的首选。QVector通常会比QList提供更好的性能,因为QVector总是按顺序在内存中存储其元素,其中QList将默认把其元素分配到堆上,分配在栈的情况只有,当sizeof(T) <= sizeof(void*)并且T已经使用Q_DECLARE_TYPEINFO声明为Q_MOVABLE_TYPE或Q_PRIMITIVE_TYPE。但是,QList在Qt api中用于传递参数和返回值。使用QList与这些api进行接口。

如果需要一个真实的链表,它保证在链表中间进行常数时间的插入,并且使用迭代器指向项目,而不是索引,可以使用QLinkedList。

  • 注意:QVector和QVarLengthArray都保证了c兼容的数组布局。QList没有。如果的应用程序必须与C API接口,这可能很重要。
  • 注意:只要被引用的项仍在容器中,QLinkedList中的迭代器和堆分配QList中的引用都是有效的。对于迭代器和QVector的引用以及非堆分配的QList则不是这样。

二、使用

1. 声明初始化

下面是一个 存储整数的 QVector 和 存储 QString 的QVector的例子:

  QVector<int> integerVector;
  QVector<QString> stringVector;

QVector将其项存储在vector(数组)中。通常,vector是用初始大小创建的。
例如,下面的代码构造了一个包含200个元素的QVector:

QVector<QString> vector(200);

元素会自动用默认构造的值初始化(如果是int、double之类的话就是 0, QString就是空字符串)。如果你想用不同的值初始化vector,将该值作为第二个参数传递给构造函数:

QVector<QString> vector(200, "Pass");

还可以在任何时候调用 fill() 来用值填充 QVector。

  QVector<QString> vector(3);
  vector.fill("Yes");
  // vector: ["Yes", "Yes", "Yes"]

  vector.fill("oh", 5);
  // vector: ["oh", "oh", "oh", "oh", "oh"]

2. 获取元素和链表信息

QVector使用基于0的索引,就像c++数组一样。要访问位于特定索引位置的项,可以使用operator [ ]。对于非const向量,operator[ ] 返回一个指向可用于赋值操作左侧的项的引用:

if (vector[0] == "Liz")
      vector[0] = "Elizabeth";

对于只读访问,另一种语法是使用at():

  for (int i = 0; i < vector.size(); ++i) {
      if (vector.at(i) == "Alfonso")
          cout << "Found Alfonso at position " << i << Qt::endl;
  }

at()可能比operator更快,因为它永远不会导致发生深度复制。 推荐使用at( )

访问存储在QVector中的数据的另一种方法是调用data()。该函数返回指向vector中第一项的指针。可以使用指针直接访问和修改存储在vector中的元素。如果需要将QVector传递给接受普通c++数组的函数,则该指针也很有用。

如果你想找到一个向量中某个特定值的所有出现情况,可以使用indexOf()或lastIndexOf()。 前者从给定的索引位置开始向前搜索,后者向后搜索。如果找到匹配项,两者都会返回匹配项的索引;否则,返回-1。例如:

  int i = vector.indexOf("Harumi");
  if (i != -1)
      cout << "First occurrence of Harumi is at position " << i << Qt::endl;

也可以用 back() 和 front() 或者 last() 和 first() 获取首尾的值。

常用获取QVector 的属性

  • contains():看QVector 是否包含特定值
  • count():获取某个元素在 QVector 里面的个数。
  • isEmpty():是不是空 向量
  • startsWith():是不是以某个元素开头

3. 常用操作

QVector提供了添加、移动和删除项的基本函数:insert()、replace()、remove()、prepend()、append()。除了append()和replace()之外,对于较大的向量,这些函数可能很慢(线性时间),因为它们需要将向量中的许多项移动内存中的一个位置。如果你想要一个在中间提供快速插入/删除的容器类,请使用QList或QLinkedList代替。

与普通的c++数组不同,QVectors可以通过调用resize()随时调整大小。如果新的大小大于旧的大小,QVector可能需要重新分配整个向量

QVector会通过预分配高达实际数据需求两倍的内存来减少重新分配的数量。
如果想预先知道QVector将包含多少项,可以调用reserve(),让QVector预先分配一定数量的内存。

还可以调用capacity()来找出QVector实际分配了多少内存。
注意,使用非const操作符和函数会导致QVector对数据进行深度复制。这是由于隐性共享。

QVector的值类型必须是可赋值的数据类型。这涵盖了常用的大多数数据类型,但编译器不允许将QWidget存储为值;相反,存储一个QWidget *。

4. 迭代Vector

与其他容器类一样,QVector提供了java风格的迭代器(QVectorIterator和QMutableVectorIterator)和stl风格的迭代器(QVector::const_iterator和QVector::iterator)。在实践中,这些很少使用,因为可以使用QVector的索引。

我也喜欢用 索引,但还是了解了解嘛。

除了QVector, Qt还提供了QVarLengthArray,这是一个非常底层的类,几乎没有为速度优化过的功能。也就是推荐不用
QVector不支持插入、添加、追加或替换对自身值的引用。 这个并不是说不能用迭代器来完成哈。

如果要在列表中间插入、修改或删除项,必须使用迭代器。QLinkedList提供了java风格的迭代器(QVectorIterator和QMutableVectorIterator)和 STL 风格的迭代器(QLinkedList::const_iterator和QLinkedList::iterator)。有关详细信息,请参阅这些类的文档。STL 的其实就是C++基础语法就不说了
看看 java 这个风格的,所谓前向遍历从 头 head -> 尾巴 tail ,后向遍历其实就是 从 尾巴 tail -> 头 head
在这里插入图片描述

  • QVectorIterator
    简单来说就是只读的迭代器,不允许修改元素,主要用的就是 hasNext() 前向遍历,hasPrevious() 反向遍历

简单的前向遍历如下:

  QVectorIterator<float> list;
  ...
  QVectorIterator<float> i(list);
  while (i.hasNext())
      qDebug() << i.next();

简单的后项向遍历如下:

  QVectorIterator<float> i(list);
  i.toBack();//把迭代器方向变成尾巴
  while (i.hasPrevious())
      qDebug() << i.previous();
  • QMutableVectorIterator
    简单来说就是可读可写的迭代器,一样支持前后迭代, hasNext() 前向遍历,hasPrevious() 反向遍历。
    同时呢,用 remove() 删除节点,用 insert() 插入节点,用setValue()来修改节点值。

简单的前向遍历如下:

  QLinkedList<float> list;
  ...
  QMutableVectorIterator<float> i(list);
  while (i.hasNext())
      qDebug() << i.next();

简单的后项向遍历如下:

  QMutableVectorIterator<float> i(list);
  i.toBack();
  while (i.hasPrevious())
      qDebug() << i.previous();

简单的增删改

  QMutableVectorIterator<int> i(list);
  while (i.hasNext()) {
      int val = i.next();
      if (val < 0) {
          i.setValue(-val);
      } else if (val == 0) {
          i.remove();
      }
  }

三、注意

  • 最大大小
    当前版本也就是Qt5 的QVector仅小于2 GB(2^31字节)。确切的值与体系结构相关,因为它依赖于管理数据块所需的开销,但该值不超过32字节。QVector中可存储元素的数量等于其大小除以每个元素的大小。

  • 内存不足的情况
    在内存分配失败的情况下,QVector将使用Q_CHECK_PTR宏,如果应用程序被编译时支持异常,该宏将抛出std::bad_alloc异常。如果禁用异常,那么内存不足是未定义的行为。
    请注意,操作系统可能会对持有大量已分配内存的应用程序施加进一步的限制,特别是大型连续内存块。这些考虑因素、此类行为的配置或任何缓解措施都超出了Qt API的范围。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/138379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

eurake原理分析以及搭建

消费者随时能够监控到服务的状态 消费者如何获取服务提供者具体的信息&#xff1f; 1&#xff09;服务提供者启动时间eureka注册自己的信息 2&#xff09;eureka保存这些信息 3&#xff09;消费者根据服务名称向eureka拉取提供者的信息 如果有多个服务提供者&#xff0c;消费者…

VS代码生成工具ReSharper v2022.3官宣首发——支持C# 11

实质上&#xff0c;ReSharper特征可用于C#&#xff0c;VB.net&#xff0c;XML&#xff0c;Asp.net&#xff0c;XAML&#xff0c;和构建脚本。 使用ReSharper&#xff0c;你可以进行深度代码分析&#xff0c;智能代码协助&#xff0c;实时错误代码高亮显示&#xff0c;解决方案范…

网络OSI(七层模型)

OSIOSI是一个理论上的网络通信模型&#xff0c;而TCP/IP则是实际运行的网络协议。TCP/IPTCP/IP (传输控制协议/网际协议) 网络通信模型 以及一整个网络传输协议家族应用层应用层协议: FTP TFTP HTTP SNMP SMTP DNS Telnet表示层 数据格式化 代码转换 数据解密/加密会话层 解除或…

低代码如何构建响应式布局前端页面

“你开发的界面为啥在我的屏幕里这么小啊&#xff1f;” “这个界面为啥在我这里会出现横向滚动条啊&#xff1f;” 大家在进行前端界面开发时&#xff0c;有没有遇到这些类似的问题呢&#xff1f;又是如何解决的呢&#xff1f; 页面响应式 在进行项目交付的场景中&#xf…

JavaEE【Spring】:Spring AOP

文章目录一、概念1、定义2、作用二、Spring AOP1、AOP 组成① 切面&#xff08;Aspect&#xff09;② 连接点&#xff08;Join Point&#xff09;③ 切点&#xff08;Pointcut&#xff09;④ 通知&#xff08;Advice&#xff09;2、实现① 添加 AOP 框架支持② 定义切面和切点Ⅰ…

都有哪些好用的设备维护管理软件?这5款值得一试

都有哪些好用的设备维护管理软件&#xff1f; 速速点进来&#xff0c;这些超高性价比的设备维护管理App/软件不容错过&#xff01; 设备是工厂及企业生存的基础&#xff0c;设备的正常运作是保证工厂及企业存活的前提&#xff0c;而要保证设备的正常运作&#xff0c;就必须要…

NLP预训练小结-从词向量到BERT

图像预训练预训练首先是在图像领域广泛应用的。设计网络结构后&#xff0c;处理图像一般是CNN的多层叠加网络结构&#xff0c;先用训练集对网络预先训练&#xff0c;处理新任务时采取相同的网络结构&#xff0c;在比较浅的几层CNN结构&#xff0c;网络参数初始化的时候可以加载…

思科路由器DHCPv6中继服务配置

配置如下&#xff1a; Router>ena Router#conf t Router(config)#host R1 R1(config)#ipv6 unicast-routing R1(config)#service dhcp R1(config)#int g0/1 R1(config-if)#ipv6 add 2001:1::1/64 R1(config-if)#no sh R1(config-if)#exit R1(config)#ipv6 local …

【自学Java】Java三目运算符

Java三目运算符 Java三目运算符教程 在 Java 语言 中&#xff0c;有一种语言可以等价于使用 if…else 进行变量的赋值操作。它就是三目运算符。 Java语言三目运算符详解 语法 Object result condition?value:value2;参数 参数描述condition条件判断符&#xff0c;一般运…

PointNet++详解(二):网络结构解析

如有错误&#xff0c;恳请指出。 在之前对PointNet与PointNet网络进行了介绍&#xff0c;接下来是对其代码的解析。 1. 论文阅读笔记 | 三维目标检测——PointNet 2. 论文阅读笔记 | 三维目标检测——PointNet 参考的github项目为&#xff1a;https://github.com/yanx27/Poi…

window10安装minio

1、首先第一步我们先下载minio 可以从官网上下不同的版本 下载地址&#xff1a;MinIO | Code and downloads to create high performance object storage 2、启动minio 切记不要双击minio&#xff0c; 1、把下载好的minio.exe放到F(我这里放到F里了)&#xff0c;在地址栏里输…

【NI Multisim 14.0编辑环境——项目管理器】

目录 序言 一、项目管理器 ⛄1.“设计工具箱”面板 ⛄2.“SPICE 网表查看器”面板 ⛄3.“LabVIEW 协同仿真终端”面板 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI Mu…

前端调试(常用)

定义调试&#xff1a;代码在某个平台运行&#xff0c;把运行时的状态通过某种方式暴露出来&#xff0c;传递给开发工具做 UI 的展示和交互&#xff0c;辅助开发者排查问题、梳理流程、了解代码运行状态等&#xff0c;这个就是调试。调试就是通过某种信道&#xff08;比如 WebSo…

clip_as_service学习过程(二)——clip主要的功能

参考链接:https://clip-as-service.jina.ai/user-guides/client/#async-encoding 一、encoding()_编码 clip_client提供 encode&#xff08;&#xff09; 函数&#xff0c;允许您以流和同步/异步方式将句子、图像发送到服务器。这里的编码意味着获取文本或图像的固定长度矢量…

【Vue中使用Echarts】在Vue中优雅的使用Echarts——图表轮播图、Echarts图表组件封装、节流函数优化图表性能

文章目录一、为什么要优雅的使用echarts二、最初的表格组件三、初步的封装四、性能优化一、为什么要优雅的使用echarts 为了提高代码的规范性、复用性&#xff0c;vue中最常用的就是将具有某些功能的代码封装到一个插件。如果没有对插件进行封装&#xff0c;在后期使用插件的时…

2022年区块链白皮书详解及内容分享

目录 导 读 技术创新稳步推进 应用路径日益清晰 产业趋稳资本活跃 多地加快战略布局 白皮书具体内容如下 导 读 区块链是构建信任的基石&#xff0c;是实现信用传递&#xff0c;价值传递的可信网络。区块链聚焦构建安全、可靠的区块链基础设施&#xff0c;让企业、政府快速…

2023北京/上海/广州/深圳NPDP产品经理国际认证招生中

产品经理国际资格认证NPDP是国际公认的唯一的新产品开发专业认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年…

【算法】动态规划(第五章习题解答)

5 动态规划 5.1 图书馆大门前有 nnn 级台阶, 你每次跨上 111 级或者 222 级, 请问等上 nnn 级台阶总共有多少种不同的方法? 设计一个算法求解上述问题, 尝试写出公式, 说明算法设计思想和时间复杂度. 算法设计&#xff1a;核心思路是函数的递归调用&#xff0c;当处理nnn级台…

drawImage 详解

背景&#xff1a; 在canvas的开发中 总会碰到drawImage这个API&#xff0c;但是里面有9个参数&#xff0c;具体代表什么意思有时候会把自己搞混乱了&#xff0c;特此记录一下&#xff0c;加深影响。 drawImage 方法有三种形态&#xff1a; drawImage(image, dx, dy) 在画布指…

【微服务】Nacos 配置管理模块

目录 一、Nacos 配置管理模块 1、配置⼀致性模型 2、Server 间的⼀致性协议 2.1、有 DB 模式&#xff08;读写分离架构&#xff09; 2.2、无 DB 模式 3、SDK 与 Server 的⼀致性协议 3.1、Nacos 1.X 3.2、Nacos 2.X 二、Nacos ⾼可⽤设计 1、全局高可用 2、同城容灾…