QT学习:容器类及QVariant类
Qt提供了一組通用的基 于模板的容器類(lèi)。對(duì)比C++的標(biāo)準(zhǔn)模板庫(kù)中的容器類(lèi),Qt 的這些容器更輕量、更安全并且更容易使用。
存儲(chǔ)在Qt容器中的數(shù)據(jù)必須是可賦值的數(shù)據(jù)類(lèi)型,也就是說(shuō),這種數(shù)據(jù)類(lèi)型必須提供一個(gè)默認(rèn)的構(gòu)造函數(shù)(不需要參數(shù)的構(gòu)造函數(shù))、一個(gè)復(fù)制構(gòu)造函數(shù)和一個(gè)賦值操作運(yùn)算符。
這樣的數(shù)據(jù)類(lèi)型包含了通常使用的大多數(shù)數(shù)據(jù)類(lèi)型,包括基本數(shù)據(jù)類(lèi)型(如int和double等)和Qt的一些數(shù)據(jù)類(lèi)型(如QString、 QDate和QTime等)。不過(guò),Qt的QObject及其他的子類(lèi)(如QWidget和Qdialog等)是不能夠存儲(chǔ)在容器中的,一個(gè)可代替的方案是存儲(chǔ)QObject及其子類(lèi)的指針。
此外Qt的容器類(lèi)也是可以嵌套的。
Qt的容器類(lèi)位遍歷其中的內(nèi)容提供了兩種方法,一種是Java風(fēng)格的迭代器,另一種是STL風(fēng)格的迭代器。
一、QList類(lèi)、QLinkedList類(lèi)、QVector類(lèi)
下圖為這三個(gè)類(lèi)的時(shí)間復(fù)雜度比較:
1、QList類(lèi)
QList<T>是迄今為止最常用的容器類(lèi),它存儲(chǔ)給定數(shù)據(jù)類(lèi)型T的一列數(shù)值。 繼承自QList類(lèi)的子類(lèi)有QltemSelection.、QQueue、 QSigalspy、 QStringList 和QTestEventList。
常用的函數(shù)有:
QList::append()、QList::prepend():在列表中進(jìn)行追加。
QList::insert()函數(shù):在列表中進(jìn)行插入。
QList<T>維護(hù)了一個(gè)指針數(shù)組,該數(shù)組存儲(chǔ)的指針指QList<T>存儲(chǔ)的列表項(xiàng)的內(nèi)容。因此,QList<T>提供了基于下標(biāo)的快速訪問(wèn)。
對(duì)于不同的數(shù)據(jù)類(lèi)型,QList<T> 采取不同的存儲(chǔ)策略,存儲(chǔ)策略有以下幾種。
(1)如果T是一個(gè)指針類(lèi)型或指針大小的基本類(lèi)型,QList<T> 會(huì)將數(shù)值直接存儲(chǔ)在它的數(shù)組中。
(2)如果QList<T>存儲(chǔ)對(duì)象的指針。則該指針指向?qū)嶋H存儲(chǔ)的對(duì)象。
2、QLinkedList類(lèi)
QLinkedList<T>是一個(gè)鏈?zhǔn)搅斜?#xff0c;它以非連續(xù)的內(nèi)存塊保存數(shù)據(jù)。
QLinkedList<T>不能使用下標(biāo),只能使用迭代器訪問(wèn)它的數(shù)據(jù)項(xiàng)。與QList相比,當(dāng)對(duì)一個(gè)很大的列表進(jìn)行插入操作時(shí),QLinkedList 具有更高的效率。
3、QVector類(lèi)
QVector<T>在相鄰的內(nèi)存中存儲(chǔ)給定數(shù)據(jù)類(lèi)型T的一組數(shù)值。在一個(gè)QVector的前部或者中間位置進(jìn)行插入操作的速度是很慢的,這是因?yàn)檫@樣的操作將導(dǎo)致內(nèi)存中的大量數(shù)據(jù)被移動(dòng),這是由QVector存儲(chǔ)數(shù)據(jù)的方式?jīng)Q定的。
QVector<T>既可以使用下標(biāo)訪問(wèn)數(shù)據(jù)項(xiàng),也可以使用迭代器訪問(wèn)數(shù)據(jù)項(xiàng)。繼承自QVector類(lèi)的子類(lèi)有QPolygon、QPolygonF 和QStack。
4、Java風(fēng)格迭代器遍歷容器
下圖是兩種類(lèi)型的 Java風(fēng)格迭代器數(shù)據(jù)類(lèi)型
Java風(fēng)格迭代器的迭代點(diǎn) 位于列表項(xiàng)的中間,而不是直接指向某個(gè)列表項(xiàng)。因此,它的迭代點(diǎn)或者在第一個(gè)列表項(xiàng)的前面,或者在兩個(gè)列表項(xiàng)之間,或者在最后一個(gè)列表項(xiàng)之后。
下面以QList為例,介紹兩種Java風(fēng)格迭代器的用法。QLinkedlist 和QVector具有與QList相同的遍歷接口,在此不再詳細(xì)講解。
(1) QList只讀遍歷方法。
以上是對(duì)列表進(jìn)行前向遍歷,后向遍歷的函數(shù)有:
QListIterator<T>::toBack():將迭代點(diǎn)移動(dòng)到最后一個(gè)列表項(xiàng)的后面。
QListIterator<T>::hasPrevious():檢查當(dāng)前迭代點(diǎn)之前是否具有列表項(xiàng)。
QListIterator<T>::Previous():返回前個(gè)列表項(xiàng)的內(nèi)容并將迭代點(diǎn)移動(dòng)到前一個(gè)列表項(xiàng)之前。
(2) QListIterator<T> 是只讀迭代器,它不能完成列表項(xiàng)的插入和刪除操作。讀寫(xiě)迭代器QMutableListIterator<T>除提供基本的遍歷操作外,還提供了insert()插入,remove()刪除操作函數(shù)和修改數(shù)據(jù)函數(shù)等。
以下代碼為QList讀寫(xiě)操作:
5、STL風(fēng)格迭代器遍歷容器
STL風(fēng)格迭代器的兩種分類(lèi)如下圖所示:
二、QMap類(lèi)和QHash類(lèi)
QMap類(lèi)和QHash類(lèi)具有非常類(lèi)似的功能,它們的差別僅在于:
QHash具有比QMap更快的查找速度;
QHash以任意的順序存儲(chǔ)數(shù)據(jù)項(xiàng),而QMap總是按照鍵(Key的順序存儲(chǔ)數(shù)據(jù);
QHash的鍵類(lèi)型Key必須提供operator==()和一個(gè)全局的qHash(Key)函數(shù),而QMap的鍵類(lèi)型Key必須提供operator<()函數(shù)。
QMap和QHash的時(shí)間復(fù)雜圖如圖:
1、QMap類(lèi)
QMap<Key,T>提供了一個(gè)從類(lèi)型為 Key的鍵到類(lèi)型為T(mén)的值的映射。
通常,QMap存儲(chǔ)的數(shù)據(jù)形式是一個(gè)鍵對(duì)應(yīng)一個(gè)值,并且按照鍵Key的順序存儲(chǔ)數(shù)據(jù)。為了能夠支持一鍵多值的情況,QMap提供了QMaps<Key,T>::insertMulti()和QMap<Key,T>::values()函數(shù)。存儲(chǔ)一鍵多值的數(shù)據(jù)時(shí),也可以使用QMultiMap<Key,T>容器,它繼承自QMap。
2、QHash 類(lèi)
QHash<Key,T>具有與QMap幾乎完全相同的API。QHash維護(hù)著一張哈希表( Hash Table),哈希表的大小與QHash的數(shù)據(jù)項(xiàng)的數(shù)目相適應(yīng)。
QHash以任意的順序組織它的數(shù)據(jù)。當(dāng)存儲(chǔ)數(shù)據(jù)的順序無(wú)關(guān)緊要時(shí),建議使用QHash作為存放數(shù)據(jù)的容器。QHash也可以存儲(chǔ)一鍵多值形式的數(shù)據(jù),它的子類(lèi)QMultiHash<Key,T>實(shí)現(xiàn)了一鍵多值的語(yǔ)義。
3. Java 風(fēng)格迭代器遍歷容器
Java風(fēng)格迭代器的兩種分類(lèi)如下圖所示:
下面舉一個(gè)例子,包含在QMap中的插入、遍歷和修改,如下代碼:
4、STL風(fēng)格迭代器遍歷容器
STL風(fēng)格迭代器的兩種分類(lèi)如下圖所示:
三、QVariant類(lèi)
QVariant類(lèi)類(lèi)似于C++的聯(lián)合(union) 數(shù)據(jù)類(lèi)型,它不僅能保存很多Qt 類(lèi)型的值,包括QColor、QBrush、 QFont、QPen、QRect、QString 和QSize等,而且也能存放Qt的容器類(lèi)型的值。Qt的很多功能都是建立在QVariant基礎(chǔ)上的,如Qt的對(duì)象屬性及數(shù)據(jù)庫(kù)功能等。
下面我們用一個(gè)例子介紹這個(gè)類(lèi)的具體用法:
總結(jié)
以上是生活随笔為你收集整理的QT学习:容器类及QVariant类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: QT学习:字符串类QString
- 下一篇: QT学习:基本对话框