歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Qt中的容器類

Qt中的容器類

日期:2017/3/1 10:49:35   编辑:Linux編程

Qt提供了兩種類型的容器類:序列容器和關聯容器。例如QVector<T>,QLinkedList<T>和QList<T>屬於序列容器,而QMap<K,T>和QHash<K,T>屬於關聯容器。

Qt提供了通用的算法,對這些容器類執行一些操作,如qSort()對一個序列容器進行排序,而qBinaryFind()在一個排過序的序列容器內執行二叉樹查找。

序列容器

QVector<T>是一個類數組的數據結構,與C++中普通的數組不同之外是:一個向量知道本身的大小並可被重置大小。將一個向量的末尾添加一個新的項相當有效,而往其前面或中間插入一個項則代價比較昂貴。

用法:

在提前知道大小的情況下:

QVector<double>vect(3);

vect[0]= 1.0;

vect[1]= 0.540302;

vect[2]= -0.416147;

在大小不可知的情況下:

QVector<double>vect;

vect.append(1.0);

vect.append(0.540302);

vect.append(-0.416147);

vect<< 1.0 << 0.540302 << -0.416147;

遍歷一個向量:

doublesum = 0.0;

for(int i = 0; i < vect.count(); ++i)

sum+= vect[i];

QLinkedList<T>是一個鏈表數據結構,它不支持隨機訪問,但可以很高效的完成插入和刪除操作。鏈表是通過迭代子來訪問的。鏈表的使用如下所示:

QLinkedList<QString>list;

list.append("Clash");

list.append("Ramones");

QLinkedList<QString>::iteratori = list.find("Ramones");

list.insert(i,"Tote Hosen");

QList<T>結合了QVector<T>和QLinkedList<T>的優點,是一個“數組-鏈表”,它的接口是基於索引的,它是一個最合適的通用容器類。

QStack<T>和QQueue<T>是兩個更實用的子類。QStack<T>在向量的基礎上增加了push(),pop()和top()方法,而QQueue<T>在鏈表的基礎上增加了enqueue(),dequeue()和head()方法。

說明:對於所有的容器類,類型T可以是基本的數據類型,如整型或雙精度型,指針類型或一個擁有默認構造函數,一個拷貝函數和一個賦值操作符的類,這些類包括QByteArray,QDateTime,QRegExp,QString和QVariant。從QObject類中繼承的子類不能作為窗口類的項,因為它們的拷貝函數和賦值操作符被禁用了。

解決辦法(Trick):將指向這些對象的指針作為容器類的項,而不是對象本身。

T也可以是一個容器類,但在寫法上要注意:

QList<QVector<double>> list;

如上,兩個>之間一定要有空格,否則編譯會將其解釋為>>而導致出錯。

容器的遍歷——迭代器

Java風格的迭代器:只讀和讀寫迭代器。只讀迭代器類有QVectorIterator<T>,QLinkedListIterator<T>和QListItrator<T>,相應的讀寫迭代器在名字中有個Mutable,如QMutableVectorIterator<T>

使用Java風格的迭代器時要注意,迭代子並不直接指向容器中的項,它們可定位在第一項之前,最後一項之後或兩者之間,如下所示:

QList<double>list;

...QListIterator<double> i(list);

while(i.hasNext()) {

do_something(i.next());

}

注:在Java風格的只讀迭代器中,可以直接對容器進行操作,無需一份拷貝,這些細節已經由相應的類自動完成了,如:

QListIterator<int>i(splitter->sizes());

while(i.hasNext()) {

do_something(i.next());

}


STL風格的迭代器;

只讀:QVector<T>::iterator,讀寫: QVector<T>::const_iterator。

如:

QList<int>list = splitter->sizes();

QList<int>::const_iteratori = list.begin();

while(i != list.end()) {

do_something(*i);

++i;

}

注意,在STL風格下,我們只能對容器的拷貝進行迭代。

//錯誤寫法:

while(i != splitter->sizes().end()) {

do_something(*i);

++i;

}


隱式共享

由於存在隱式共享,拷貝一個容器類代價並不高,與復制一個指針的代價差不多。僅當某個容器的拷貝內容發生變化時才進行真正的拷貝,有點像Linux中父過程與子進程之間的“寫時復制”共享數據。隱式共享鼓勵對象通過傳值的方式返回。

Qt中所有的容器類以及許多其他的類都使用了隱式共享,包括QByteArray,Qbrush, AFont, QImage,QPixmap和QString。這些類通過傳值的方式傳遞時非常高效,不管是作為函數參數或是作為函數返回值。

隱式共享保證了數據只有被修改時才會進行真正的復制。所以在Qt中,盡管使用只讀形式的接口。

關聯容器

Qt提供了兩個主要的關聯容器類:QMap<K,T>和QHash<K,T>。

訪問方式如下代碼所示:

QMap<QString,int> map;

map.insert("eins",1);

map.insert("sieben",7);

map.insert("dreiundzwanzig",23);

map["eins"]= 1;

map["sieben"]= 7;

map["dreiundzwanzig"]= 23;


intval = map.value("dreiundzwanzig");

intseconds = map.value("delay", 30);帶默認值。


QMultiMap是一種1對多的映射容器。

QHash與QMap的接口類似,不過它是無序的,它也有一個變體QMultiHash。


通用算法

<QtAlgorithms>包含了一些通用的全局模板函數,實現了操作於容器類數據的通用算法。

如qFind(),qCopy(), qFill(), qSort()等。


類容器類

與容器類有許多共性的三個類是:QString, QByteArray, QVariant。

QString的值是16位Unicode值,包含ASCII和Latin-1。QString可認為是一個元素為QChar類型的向量,它可嵌入’\0’,length()函數返回的值包含嵌入的’\0’。QString支持+和+=連接字符串,也可以使用append()方式。也可以使用sprintf()方法連接不同的字符串,如:

str.sprintf("%s%.1f%%", "perfect competition", 100.0);

顯示地將一個constchar*型字符串轉換為QString類型的方法如下:

constchar* str = “This is a test”;

QStringqstr = (QString)str;

或qstr= QStirng::fromAscii(str)或qstr= QString::fromLatin1();

將QString轉變為constchar*型的步驟如下:

  1. 先使用toAscii()或toLatin1()返回一個QByteArray類型的對象

  2. 使用QByteArray::data()或QByteArray::constData()將其轉換為constchar*型。

QString與中文顯示問題

QString本身是支持中文顯示的,它默認是支持unicode的。要使QString能正常地顯示中文,必須傳遞合適的unicode。有兩種方法:

  1. 利用QTextCodec的toUnicode()方法。

如: w.setWindowTitle(QTextCodec::codecForName("gb2312")->toUnicode("這是一個測試!"));

  1. 利用QTextCodec的靜態方法,如setCodecForCStrings等。

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));

優先選擇第二種方法。

Copyright © Linux教程網 All Rights Reserved