天天看點

QT5開發||07、QT5常見類(2)—容器類一、常見容器類二、QList類、 QLinkedList 類和QVector類

摘要

在Qt庫中為我們提供了一系列的基于模闆的容器類。這些類可以被用來存儲特定類型的項。這些容器類都是隐式共享的,可重入的,并且在速度上進行了優化,記憶體占用少,内聯代碼擴充少,進而可以産生更小的可執行檔案。此外,當他們被用作隻讀容器時,還是線程安全的。

一、常見容器類

在開發一個較高性能需求的應用程式時,程式員會比較關注這些容器類的運

行效率,表2.1列出了QList、QLinkedList和QVector容器 的時間複雜度比較。

容器類 查找 插入 頭部添加 尾部添加
QList O(1) O(n) Amort.O(1) Amort.O(1)
QLinkedList O(n) O(1) O(1) O(1)
QVector O(1) O(n) O(n) Amort.O(1)

二、QList類、 QLinkedList 類和QVector類

1、QList類

QList是迄今為止最常用的容器類,它存儲給定資料類型T的一列數值。

QList不僅提供了可以在清單進行追加的QList::append()和list::prepend()函數,還提供了在清單中間完成插入操作的函數QList:insert()。

QList維護了一個指針數組,該數組存儲的指針指向QList存儲的清單項的内容。

對于不同的資料類型,QList采取不同的存儲政策,存儲政策有以下幾種。

(1)如果T是一個指針類型或指針大小的基本類型(即該基本類型占有的位元組數和指針類型占有的位元組數相同),QList 會将數值直接存儲

在它的數組中。

(2)如果QList存儲對象的指針,則該指針指向實際存儲的對象。

相關例子:

#include <QDebug> 
int main(int argc,char *argv[])
{
    QList<QString>list;
    {
        QString str("This is a test string");
        list<<str;
    }
    qDebug()<<list[0]<<"How are you!";
    return 0;
}
           

2. QLinkedList類

QLinkedList是一個鍊式清單,它以非連續的記憶體塊儲存資料。

QLinkedList不能使用下标,隻能使用疊代器通路它的資料項。

3. QVector 類

QVector在相鄰的記憶體中存儲給定資料類型T的一組數值。

QVector既可以使用下标通路資料項,也可以使用疊代器通路資料項。

4. Java風格疊代器周遊容器

Java風格的疊代器是Qt 4新加入的一個功能。

對于每一個容器類,Qt都提供了兩種類型的Java風格疊代器資料類型,即隻讀通路和讀寫通路,其分類見下表。

容器類 隻讀疊代器類 讀寫疊代器類
QList,QQueue QListIterator QMutableListIterator
QLinkedList QLinkedListIterator QMutableLinkedListIterator
Qvector,QStack QVectorIterator QMutableVectorIterator

5. STL風格疊代器周遊容器

對于每一個容器類,Qt都提供了兩種類型的STL風格疊代器資料類型:一種提供隻讀通路;另- -種提供讀寫通路。

三、QMap類和QHash類

QMap類和QHash類具有非常類似的功能,它們的差别僅在于:

●QHash具有比QMap更快的查找速度;

●QHash以任意的順序存儲資料項,而QMap總是按照鍵Key順序存儲資料;

●QHash的鍵類型Key必須提供operator==()和一個全局的qHash(Key)函數,

而QMap的鍵類型Key必須提供operator<()函數。

二者的時間複雜度比較見下表。

容器類 鍵查找 插入
平均 最壞
QMap Olog(n) Olog(n)
QHash Amort.O(1) O(n)

1. QMap類

QMap<Key,T>提供了一個從類型為Key的鍵到類型為T的值的映射。

2. QHash類

QHash<Key,T>具有與QMap幾乎完全相同的API。QHash維護着一張哈希表(HashTable),哈希表的大小與QHash的資料項的數目相适應。

3. Java風格疊代器周遊容器

對于每一個容器類,Qt都提供了兩種類型的Java風格疊代器資料類型:一種提供隻讀通路;另一種提供讀寫通路。

下面的例子完成了QMap中的插入、周遊和修改。

#include <QDebug>
int main(int argc,char *argv[])
{
    QMap<QString,QString>map;
    map.insert("beijing","111");
    map.insert("shanghai","021");
    map.insert("nanjingjing","025");
    QMaplterator<QString,QString>i(map);
    for(;i.hasNext();)
            qDebug()<<" "<<i.key()<<" "<<i.next().value();
    QMutableMaplterator<QString,QString>mi(map);
    if(mifindNex(111"))
        mi.setValue("010");

    QMaplterator<QString,QString> modi(map); 
    qDebug()<<" ";
    for(;modi.hasNext();)
            qDebug()<<" "<<modi.key()<<" "<<modi.next().value();
    return 0;
}
           

四、QVariant類

1、QVariant類及QVariant與自定義資料類型轉換的方法

這個類型相當于是Java裡面的Object,它把絕大多數Qt提供的資料類型都封裝起來,起到一個資料類型“擦除”的作用。比如我們的 table

單元格可以是string,也可以是int,也可以是一個顔色值,那麼這麼多類型怎麼傳回呢?于是,Qt提供了這個QVariant類型,你可以把這

很多類型都存放進去,到需要使用的時候使用一系列的to函數取出來即可。

比如你把int包裝成一個QVariant,使用的時候要用 QVariant::toInt()重新取出來。這裡需要注意的是,QVariant類型的放入和取出必須是

相對應的,你放入一個int就必須按int取出,不能用toString(), Qt不會幫你自動轉換。資料核心無非就是一個 union,和一個标記類型的

type:傳遞的是整數 123,那麼它union存儲整數123,同時type标志Int;如果傳遞字元串,union存儲字元串的指針,同時type标志

QString。

QVariant 屬于 Qt 的Core子產品,屬于Qt的底層核心之一,ActiveQt、QtScript、QtDeclarative等都嚴重依賴于QVariant。

2、QVariant 可以儲存很多Qt的資料類型

QVariant包括QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、

QRegion、QSize和QString,并且還有C++基本類型,如 int、float等。QVariant還能儲存很多集合類型,

如QMap<QSTRING, QVariant>, QStringList和QList。item view classes,資料庫子產品和QSettings都大量使用了QVariant類,,以友善

我們讀寫資料。

3、QVariant也可以進行嵌套存儲,例如:

QMap<QString, QVariant> pearMap;   
pearMap["Standard"] = 1.95;   
pearMap["Organic"] = 2.25;   

QMap<QString, QVariant> fruitMap;   
fruitMap["Orange"] = 2.10;   
fruitMap["Pineapple"] = 3.85;   
fruitMap["Pear"] = pearMap;
           

QVariant被用于建構Qt Meta-Object,是以是QtCore的一部分。當然,我們也可以在GUI子產品中使用,例如:

QIcon icon("open.png");   
QVariant variant = icon;   
// other function   
QIcon icon = variant.value<QIcon>();
           

我們使用了value()模版函數,擷取存儲在QVariant中的資料。這種函數在非GUI資料中同樣适用,但是,在非GUI子產品中,我們通常使用

toInt()這樣的一系列函數,如toString()等。

至此,QT常見容器類就介紹完畢了!

繼續閱讀