ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

学习QT之QString详解

2020-03-02 13:09:20  阅读:957  来源: 互联网

标签:QT str2 str1 详解 QString str 字符串 数据结构


学习QT之QString详解


QString类保存16位Unicode值,提供了丰富的操作、查询和转换函数。该类还进行了使用隐式共享、高效的内存分配策略等多方面的优化。

一、字符串常用操作

字符串的操作

函数 说明
str.append(“xxx”) 在一个字符串的末尾追加另一个字符串
str.sprintf("%s",“HelloWorld”) 给字符串赋值为HelloWorld
str=QString("%1 is good").arg(“Bike”) arg()函数占位后填
str.insert(1,“Hello”) 在字符串第二个字符处插入"Hello"
str.prepend(“Hello”) 在源字符串的开头插入另一个字符串
str.replace() 用指定的字符串代替原字符串中的某些字符串
QString::trimmed() 移除字符串两端的空白字符
QString::simplified() 移除字符串两端的空白字符,使用单个空白字符" "代替字符串中出现的空白字符

字符串的查询

函数 说明
str.startWith(’@’,Qt::CaseSensitive) 是否以特定字符开头
str.endWith(’#’,Qt::CaseSensitive) 是否以特定字符结尾
str.indexof(’*’,Qt::CaseSensitive) 返回字符串中特定字符的索引
str.contains(‘Welcome’,Qt::CaseSensitive) 查询字符串中是否包含特定字符串

字符串的转换

函数 说明
str.toInt(&ok,16) //16为进制,默认为10 将字符串转换为整型值
str.toAscii() 返回一个ASCII编码的8位字符串
str.Latin1() 返回一个Latin-1编码的8位字符串
str.toUtf8() //UTF-8是ASCII码的超集 返回一个UTF-8编码的8位字符串
str.toLocal8Bit() 返回一个系统本地编码的8位字符串

NULL字符串和空字符串的区别:一个NULL字符串就是使用QString的默认构造函数或者使用"(const char*)0"作为参数的构造函数创建的QString字符串对象;而一个空字符串是一个大小为0的字符串。一个NULL字符串一定是一个空字符串,而一个空字符串未必是一个NULL字符串。

二、字符串的隐式共享

隐式共享又称回写复制。当两个对象共享同一份数据(通过浅拷贝实现数据块的共享)时,如果数据不改变,则不进行数据的复制。而当某个对象需要改变数据时,则进行深拷贝。

程序在处理共享对象时,使用深拷贝和浅拷贝这两种方法复制对象。所谓深拷贝,是指生成对象的一个完整的复制品,执行一个深拷贝的代价是比较昂贵的,要占用更多的内存和CPU资源;而浅拷贝的效率则很高,它仅需设置一个指向共享数据块的指针及修改引用计数的值。

隐式共享可以降低对内存和CPU资源的使用率,提高程序的运行效率。它使得在函数(如参数、返回值)中使用值传递更有效率。

QString类采用隐式共享计数,将深拷贝和浅拷贝邮寄地结合起来,下面通过一个例子来说明。

QString str1="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中支持隐式共享的类,还包括:

  1. 所有的容器类。
  2. QByteArray、QBrush、QPen、QPalette、QBitmap、QImage、QPixmap、QCursor、QDir、QFont和QVariant等。

三、字符串的内存分配策略

QString在一个连续的内存块中保存字符串数据。当字符串的长度不断增长是,QString需要重新分配内存空间,以便有足够的控件保存增加的字符串。QString使用的内存分配策略如下:

  1. 每次分配4个字符空间,直到大小为20。
  2. 在20~4084之间,QString分配的内存块大小以2倍的速度增长。
  3. 从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字节)。

贝勒里恩 发布了48 篇原创文章 · 获赞 5 · 访问量 2593 私信 关注

标签:QT,str2,str1,详解,QString,str,字符串,数据结构
来源: https://blog.csdn.net/Mr_robot_strange/article/details/104609521

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有