學習QT之QString詳解


相關資料:

https://www.icode9.com/content-4-646552.html 學習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中支持隱式共享的類,還包括:

所有的容器類。
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字節)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM