Qt编程进阶(1):字符串优化 qt设置字符编码
bigegpt 2024-12-23 08:48 3 浏览
Qt字符串类(QString)进行了多方面的优化。
隐式共享
隐式共享(implicit sharing)又称为回写复制(copy on write)。当两个对象共享同一份数据时(通过浅拷贝实现数据块的共享),如果数据不改变,则不进行数据的复制。而当某个对象需要改变数据时,则执行深拷贝。
程序在处理共享对象时,使用深拷贝和浅拷贝这两种方法复制对象。所谓深拷贝,就是生成对象的一个完整的复制品;而浅拷贝则是一个引用复制(如仅复制指向共享数据的指针)。
显然,执行一个深拷贝的代价是比较昂贵的,要占用更多的内存和CPU资源;而浅拷贝的效率则很髙,它仅需设置一个指向共享数据块的指针及修改引用计数的值。
隐式共享可以降低对内存和CPU资源的使用率,提高程序的运行效率。它使得在函数中(如参数、返回值)使用值传递更有效率。
QString类釆用隐式共享技术,将深拷贝和浅拷贝有机地结合起来。
下面通过一个例子来具体介绍隐式共享是如何工作的。
QString str1 = "data"; //初始化一个内容为“data”的字符串
QString str2 = str1; //(a)
str2[3] = ‘e'; //(b)
str2[0] = ‘f’; //(c)
str1 = str2; //(d)
其中,
- (a)QString str2 = str1: 将该字符串对象str1赋值给另一个字符串str2 (由QString的复制构造函数完成str2的初始化),此时str2 = ”data"。在对str2赋值的时候,将发生一次浅拷贝,导致两个QString对象都指向同一个数据结构。该数据结构除了保存字符串“data”外,还保存了一个引用计数器,以记录字符串数据的引用次数。在这里,因为str1和str2指向同一个数据结构,所以计数器的值为2。
- (b) str2[3] = ‘e':对QString对象str2的修改,将会导致一次深拷贝,使得str2对象指向一个新的、不同于str1所指的数据结构(该数据结构的引用计数为1,因为只有str2指向这个数据结构),同时修改原来的str1指向的数据结构,设置它的引用计数为1。此时,只有QString对象str1指向该数据结构)。继而在这个str2指向的、新的数据结构上完成数据的修改。引用计数为1意味着这个数据没有被共享。此时str2 =”date",str1=”data"。
- (c) str2[0] = ‘f’:进一步对QString对象str2进行修改,但这个操作不会引起任何形式的复制,因为str2指向的数据结构没有被共享。此时,str2 = "fate”, str1 = "data"。
- (d) str1 = str2:将str2赋值给str1。此时,str1将它指向的数据结构的引用计数器的值修改为0,也就是说,没有QString对象再使用这个数据结构了。因此,str1指向的数据结构将会从内存中释放掉。该操作的结果是,QString对象str1和str2都指向字符串为“fate”的数据结构,该数据结构的引用计数为2。
Qt中支持隐式共享的类还包括:所有的容器类;QByteArray、QBrush、QPen、QPalette、QBitmap、QImage、QPixmap、QCursor、QDir、QFont和QVariant等。
内存分配策略
QString在一个连续的内存块中保存字符串数据。当字符串的长度不断增长时,QString需要重新分配内存空间,以便有足够的空间保存增加的字符串。QString使用的内存分配策略如下。
每次分配4个字符空间,直到大小为20;
在20?4084之间,QString分配的内存块大小以2倍的速度增长;
从4084开始,每次以2048个字符大小(4096字节,即4KB)的步长增长。
下面举例具体说明QString在后台是如何运行的:
QString test()
{
QString str;
for(int i=0;i<9000;++i)
str.append(“a”);
return str;
}
首先定义了一个QString对象str,然后为它追加9000个字符。根据QString的内存分配策略,这个循环操作将导致14次内存重分配:4、8、16、20、52、116、244、500、1012、2036、4084、6132、8180、10228。最后一次内存重分配操作后,QString对象str具有一个10228个Unicode字符大小的内存块(20456字节),其中有9000个字符空间被使用(18000字节)。
————————————————
觉得有用的话请关注点赞,谢谢您的支持!
对于本系列文章相关示例完整代码有需要的朋友,可关注并在评论区留言!
相关推荐
- 了解Linux目录,那你就了解了一半的Linux系统
-
大到公司或者社群再小到个人要利用Linux来开发产品的人实在是多如牛毛,每个人都用自己的标准来配置文件或者设置目录,那么未来的Linux则就是一团乱麻,也对管理造成许多麻烦。后来,就有所谓的FHS(F...
- Linux命令,这些操作要注意!(linux命令?)
-
刚玩Linux的人总觉得自己在演黑客电影,直到手滑输错命令把公司服务器删库,这才发现命令行根本不是随便乱用的,而是“生死簿”。今天直接上干货,告诉你哪些命令用好了封神!喜欢的一键三连,谢谢观众老爷!!...
- Linux 命令速查手册:这 30 个高频指令,拯救 90% 的运维小白!
-
在Linux系统的世界里,命令行是强大的武器。对于运维小白而言,掌握一些高频使用的Linux命令,能极大提升工作效率,轻松应对各种系统管理任务。今天,就为大家奉上精心整理的30个Linu...
- linux必学的60个命令(linux必学的20个命令)
-
以下是Linux必学的20个基础命令:1.cd:切换目录2.ls:列出文件和目录3.mkdir:创建目录4.rm:删除文件或目录5.cp:复制文件或目录6.mv:移动/重命名文件或目录7....
- 提高工作效率的--Linux常用命令,能够决解95%以上的问题
-
点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...
- 15 个实用 Linux 命令(linux命令用法及举例)
-
Linux命令行是系统管理员、开发者和技术爱好者的强大工具。掌握实用命令不仅能提高效率,还能解锁Linux系统的无限潜力,本文将深入介绍15个实用Linux命令。ls-列出目录内容l...
- Linux 常用命令集合(linux常用命令全集)
-
系统信息arch显示机器的处理器架构(1)uname-m显示机器的处理器架构(2)uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部件-(SMBIOS/DM...
- Linux的常用命令就是记不住,怎么办?
-
1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...
- Linux常用文件操作命令(linux常用文件操作命令有哪些)
-
ls命令在Linux维护工作中,经常使用ls这个命令,这是最基本的命令,来写几条常用的ls命令。先来查看一下使用的ls版本#ls--versionls(GNUcoreutils)8.4...
- Linux 常用命令(linux常用命令)
-
日志排查类操作命令查看日志cat/var/log/messages、tail-fxxx.log搜索关键词grep"error"xxx.log多条件过滤`grep-E...
- 简单粗暴收藏版:Linux常用命令大汇总
-
号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部下午好,我的网工朋友在Linux系统中,命令行界面(CLI)是管理员和开发人员最常用的工具之一。通过命令行,用户可...
- 「Linux」linux常用基本命令(linux常用基本命令和用法)
-
Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用的基本命令分享给大家一下,希望可以帮助你们。总结送免费学习资料(包含视频、技术学习路线图谱、文档等)1、显示日期的指令:d...
- Linux的常用命令就是记不住,怎么办?于是推出了这套教程
-
1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...
- Linux的30个常用命令汇总,运维大神必掌握技能!
-
以下是Linux系统中最常用的30个命令,精简版覆盖日常操作核心需求,适合快速掌握:一、文件/目录操作1.`ls`-列出目录内容`ls-l`(详细信息)|`ls-a`(显示隐藏文件)...
- Linux/Unix 系统中非常常用的命令
-
Linux/Unix系统中非常常用的命令,它们是进行文件操作、文本处理、权限管理等任务的基础。下面是对这些命令的简要说明:**文件操作类:*****`ls`(list):**列出目录内容,显...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)