C++ Qt開發:使用順序容器類

微軟技術分享發表於2023-12-10

當我們談論程式設計中的資料結構時,順序容器是不可忽視的一個重要概念。順序容器是一種能夠按照元素新增的順序來儲存和檢索資料的資料結構。它們提供了簡單而直觀的方式來組織和管理資料,為程式設計師提供了靈活性和效能的平衡。

Qt 中提供了豐富的容器類,用於方便地管理和運算元據。這些容器類涵蓋了各種不同的用途,從簡單的動態陣列到複雜的對映和集合。本章我們將主要學習順序容器,順序容器是一組強大而靈活的資料結構,用於按照元素新增的順序儲存和管理資料。Qt提供了多種順序容器,每種都具有獨特的特性,這些容器包括向量、列表、佇列、棧等,每種都有特定的適用場景。

當然了STL標準模板中也存在這些容器,Qt 的容器類與標準模板庫(STL)中的容器類有些相似,但也有一些不同之處。以下是 Qt 容器類相對於STL的一些特點和優勢:

  1. 可自動共享資料:
    • Qt 容器類使用了引用計數的技術,能夠自動共享資料,減少記憶體佔用。當一個容器物件複製另一個容器物件時,它們可以共享底層資料而不是進行深複製。
  2. 隱式共享:
    • Qt 容器類透過隱式共享實現了高效的資料共享。只有在發生寫操作時,才會執行深複製,從而減少不必要的開銷。
  3. 可跨執行緒使用:
    • Qt 容器類支援在多執行緒環境中安全使用,透過顯式共享(QExplicitlySharedDataPointer)和不顯式共享兩種方式,方便在多執行緒應用中進行資料處理。
  4. 提供了一些額外的功能:
    • Qt 的容器類在標準容器的基礎上提供了一些額外的功能,例如對 Unicode 字串的特殊支援(QString),以及一些便捷的成員函式,使得容器的使用更為方便。
  5. 記憶體管理:
    • Qt 容器類負責管理其元素的記憶體,使得記憶體的分配和釋放不需要額外的手動管理,減輕了開發者的負擔。
  6. 直觀的 API 設計:
    • Qt 的容器類 API 設計考慮了 Qt 的整體框架,採用了一致而直觀的命名規範,使得使用者更容易理解和記憶容器類的介面。
  7. 與其他 Qt 類的整合:
    • Qt 容器類能夠無縫地與其他 Qt 類和框架整合,例如與訊號和槽機制一起使用,使得在 Qt 應用程式中的開發更為方便。

在某些特定的場景和需求下,STL 的容器類可能更適合使用。然而,在使用 Qt 框架的情況下,Qt 容器類通常能夠提供更好的整合和一些額外的特性。選擇使用哪種容器類取決於具體的專案需求和開發者的偏好。

1.1 QList 動態陣列容器

QList 是 Qt 中常用的動態陣列類,它提供了動態大小的陣列,支援在列表的兩端和中間快速插入、刪除元素。適用於需要動態管理元素集合的場景,使得對列表的操作更加簡便。

以下是 QList 的一些常用函式:

函式 功能
QList::QList() 建構函式,建立一個空的 QList 物件。
QList::QList(const QList &other) 複製建構函式,建立一個與給定列表相同的 QList 物件。
QList::append(const T &value) 在列表末尾新增一個元素。
QList::prepend(const T &value) 在列表開頭新增一個元素。
QList::replace(int i, const T &value) 替換列表中索引為 i 的元素為給定的值。
QList::removeAt(int i) 移除列表中索引為 i 的元素。
QList::removeOne(const T &value) 移除列表中第一個匹配給定值的元素。
QList::removeAll(const T &value) 移除列表中所有匹配給定值的元素。
QList::takeAt(int i) 移除並返回列表中索引為 i 的元素。
QList::takeFirst() 移除並返回列表中的第一個元素。
QList::takeLast() 移除並返回列表中的最後一個元素。
QList::insert(int i, const T &value) 在列表中索引為 i 的位置插入一個元素。
QList::contains(const T &value) const 判斷列表中是否包含給定值。
QList::count(const T &value) const 統計列表中匹配給定值的元素數量。
QList::indexOf(const T &value, int from = 0) const 返回給定值在列表中的第一個匹配項的索引,從指定位置 from 開始搜尋。
QList::lastIndexOf(const T &value, int from = -1) const 返回給定值在列表中的最後一個匹配項的索引,從指定位置 from 開始反向搜尋。
QList::isEmpty() const 判斷列表是否為空。
QList::size() const 返回列表中元素的數量。
QList::clear() 清空列表,移除所有元素。
QList::operator=() 過載賦值運算子,將一個列表賦值給另一個列表。
QList::operator==() 過載相等運算子,判斷兩個列表是否相等。
QList::operator!=() 過載不等運算子,判斷兩個列表是否不相等。

以上是 QList 的一些常用函式及其功能,這些函式允許開發者對列表進行新增、刪除、替換、查詢等操作,以滿足不同場景的需求。

1.1.1 主要特點

  1. 動態陣列: QList 是動態大小的陣列,可以根據需要自動調整大小。
  2. 泛型: QList 是泛型容器,可以儲存任意型別的資料。
  3. 可變大小: 列表的大小可以動態改變,元素的插入和刪除操作都很高效。
  4. 雙向迭代器: QList 提供了雙向迭代器,可以方便地從前往後或從後往前遍歷列表。

1.1.2 如何使用

如下所示的程式碼中我定義了兩個QList容器,分別是StringPtrAStringPtrB透過使用不同的容器操作函式對其進行簡單的增加插入替換刪除和移動操作,如下程式碼所示;

#include <QCoreApplication>
#include <iostream>
#include <QList>

void Display(QList<QString> &ptr)
{
    std::cout << "-----------------------------" << std::endl;
    for(qint32 x=0;x<ptr.count();x++)
    {
        // std::cout << ptr[x].toStdString().data() << std::endl;
        std::cout << (ptr.at(x)).toStdString().data() << std::endl;
    }
    std::cout << std::endl;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QList<QString> StringPtrA;
    QList<QString> StringPtrB;

    // 新增三個成員
    StringPtrA.append("admin");
    StringPtrA.append("guest");
    StringPtrA.append("lyshark");
    Display(StringPtrA);

    // 在首部插入hanter
    StringPtrA.prepend("hanter");
    Display(StringPtrA);

    // 在第0的位置插入lucy
    StringPtrA.insert(0,QString("lucy"));
    Display(StringPtrA);

    // 替換原來的admin為全拼
    StringPtrA.replace(1,"Administrator");
    Display(StringPtrA);

    // 刪除第0個元素
    StringPtrA.removeAt(0);
    Display(StringPtrA);

    // 刪除首部和尾部
    StringPtrA.removeFirst();
    StringPtrA.removeLast();

    // 移動兩個變數
    StringPtrA.move(0,1);
    Display(StringPtrA);

    // 將兩個list容器對調交換
    StringPtrB = {"youtube","facebook"};
    StringPtrA.swap(StringPtrB);
    Display(StringPtrA);
    return a.exec();
}

上述程式碼我們只是對字串進行了連結串列管理,其實Qt中支援管理結構體,首先要定義一個特有的結構體MyStruct當結構體被賦值後就可以像陣列一樣靈活的運算元據,當然在使用結構體時我們傳入的應該是QList<MyStruct>結構體的名字,在遍歷時可以有三種方式,第一種時傳統的迴圈依次輸出元素,這裡我們說說使用QListIteratorQMutableListIterator來輸出元素的區別。

#include <QCoreApplication>
#include <iostream>
#include <QList>
#include <QListIterator>
#include <QMutableListIterator>

struct MyStruct
{
    qint32 uid;
    QString uname;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QList<MyStruct> ptr;
    MyStruct str_ptr;

    str_ptr.uid = 1001;
    str_ptr.uname = "admin";
    ptr.append(str_ptr);

    str_ptr.uid = 1002;
    str_ptr.uname = "guest";
    ptr.append(str_ptr);

    // 使用傳統方式遍歷資料
    for(qint32 x=0;x<ptr.count();x++)
    {
        std::cout << ptr.at(x).uid << std::endl;
        std::cout << ptr[x].uname.toStdString().data() << std::endl;
    }

    // 使用只讀迭代器遍歷
    QListIterator<MyStruct> x(ptr);
    while(x.hasNext())
    {
        // peeknext讀取下一個節點,但不影響指標變化
        std::cout << x.peekNext().uid << std::endl;
        std::cout << (x.peekNext().uname).toStdString().data() << std::endl;
        // 最後將x指標指向下一個資料
        x.next();
    }

    // 使用讀寫迭代器:如果uid=1002則將guest改為lyshark
    QMutableListIterator<MyStruct> y(ptr);
    while(y.hasNext())
    {
        // y.peekNext().uid = 9999;
        if(y.peekNext().uid == 1002)
        {
            y.peekNext().uname = "lyshark";
        }
        y.next();
    }
    return a.exec();
}

其實QListIteratorQMutableListIterator 都是用於遍歷 QList 容器的迭代器類。區別是QListIterator 是一個只讀迭代器,用於遍歷 QList 容器中的元素。它提供了一個方便的方式來訪問容器中的元素,支援前向和後向遍歷。而QMutableListIterator 是一個可變迭代器,除了支援讀取元素外,還允許修改 QList 中的元素。它提供了修改元素的介面,使得在遍歷的同時可以對容器進行修改。

QListIterator 主要函式和特點

  • QListIterator(const QList<T> &list): 建構函式,用於初始化迭代器並關聯到給定的 QList
  • hasNext() const: 檢查是否有下一個元素。
  • next(): 返回當前元素並將迭代器移動到下一個元素。
  • peekNext() const: 返回當前元素但不移動迭代器。
  • toFront(): 將迭代器移動到列表的第一個元素。
  • toBack(): 將迭代器移動到列表的最後一個元素。

QMutableListIterator 主要函式和特點

  • QMutableListIterator(QList<T> &list): 建構函式,用於初始化可變迭代器並關聯到給定的 QList
  • hasNext() const: 檢查是否有下一個元素。
  • next(): 返回當前元素並將迭代器移動到下一個元素。
  • peekNext() const: 返回當前元素但不移動迭代器。
  • toFront(): 將迭代器移動到列表的第一個元素。
  • toBack(): 將迭代器移動到列表的最後一個元素。
  • remove(): 移除迭代器當前位置的元素。
  • setValue(const T &value): 將迭代器當前位置的元素設定為給定值。

這兩個迭代器類提供了方便而靈活的方式來遍歷和操作 QList 中的元素,根據需要選擇合適的迭代器。

1.2 QLinkeList 雙向連結串列容器

QLinkedList 是 Qt 中的雙向連結串列實現,與 QList 不同,它不是基於陣列的動態容器,而是基於連結串列的資料結構。QLinkedList 提供了連結串列特有的靈活性,適用於需要在任意位置高效插入和刪除元素的場景。在一些訪問元素的場景中,由於連結串列的非連續儲存特性,可能比陣列容器的訪問效率稍低。選擇使用 QLinkedList 還是其他容器,取決於具體的使用需求。

以下是 QLinkedList 的一些常用函式:

函式 功能
QLinkedList::QLinkedList() 建構函式,建立一個空的 QLinkedList 物件。
QLinkedList::QLinkedList(const QLinkedList &other) 複製建構函式,建立一個與給定連結串列相同的 QLinkedList 物件。
QLinkedList::append(const T &value) 在連結串列末尾新增一個元素。
QLinkedList::prepend(const T &value) 在連結串列開頭新增一個元素。
QLinkedList::replace(const_iterator before, const T &value) 替換連結串列中給定迭代器位置的元素為給定的值。
QLinkedList::remove(const T &value) 移除連結串列中所有匹配給定值的元素。
QLinkedList::removeOne(const T &value) 移除連結串列中第一個匹配給定值的元素。
QLinkedList::removeAt(int i) 移除連結串列中索引為 i 的元素。
QLinkedList::takeAt(int i) 移除並返回連結串列中索引為 i 的元素。
QLinkedList::takeFirst() 移除並返回連結串列中的第一個元素。
QLinkedList::takeLast() 移除並返回連結串列中的最後一個元素。
QLinkedList::insert(const_iterator before, const T &value) 在連結串列中給定迭代器位置插入一個元素。
QLinkedList::contains(const T &value) const 判斷連結串列中是否包含給定值。
QLinkedList::count(const T &value) const 統計連結串列中匹配給定值的元素數量。
QLinkedList::indexOf(const T &value) const 返回給定值在連結串列中的第一個匹配項的索引。
QLinkedList::lastIndexOf(const T &value) const 返回給定值在連結串列中的最後一個匹配項的索引。
QLinkedList::isEmpty() const 判斷連結串列是否為空。
QLinkedList::size() const 返回連結串列中元素的數量。
QLinkedList::clear() 清空連結串列,移除所有元素。
QLinkedList::begin() 返回指向連結串列第一個元素的迭代器。
QLinkedList::end() 返回指向連結串列最後一個元素之後的迭代器。

QLinkedList 提供了與 QList 類似的操作,但由於其基於雙向連結串列實現,特別適合於需要頻繁插入和刪除操作的場景。在使用上,QLinkedList 提供了一些額外的函式,如 replaceinsert 等,可以更方便地操作連結串列中的元素。

1.2.1 主要特點

  1. 雙向連結串列: QLinkedList 使用雙向連結串列結構,每個節點儲存一個元素以及指向前後節點的指標,支援高效的插入和刪除操作。
  2. 泛型: QLinkedList 是泛型容器,可以儲存任意型別的資料。
  3. 可變大小: 連結串列的大小可以動態改變,元素的插入和刪除操作在任意位置都很高效。
  4. 雙向迭代器: QLinkedList 提供了雙向迭代器,可以方便地從前往後或從後往前遍歷連結串列。

1.2.2 如何使用

QLinkeList其實就是動態連結串列結構,資料的儲存非連續,訪問時無法直接使用下標定位,只能透過迭代器迭代尋找,這是其與QList的本質區別,其引數定義與QList基本一致,在使用上並沒有本質上的區別。

#include <QCoreApplication>
#include <iostream>
#include <QLinkedList>
#include <QLinkedListIterator>
#include <QMutableLinkedListIterator>

struct MyStruct
{
    qint32 uid;
    QString uname;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QLinkedList<MyStruct> ptr;
    MyStruct str_ptr;

    str_ptr.uid = 1001;
    str_ptr.uname = "admin";
    ptr.append(str_ptr);

    str_ptr.uid = 1002;
    str_ptr.uname = "guest";
    ptr.append(str_ptr);


    // 使用只讀迭代器遍歷: 從前向後遍歷
    QLinkedListIterator<MyStruct> x(ptr);
    while(x.hasNext())
    {
        std::cout << x.peekNext().uid << std::endl;
        x.next();
    }

    // 使用只讀迭代器遍歷: 從後向前遍歷
    for(x.toBack();x.hasPrevious();x.previous())
    {
        std::cout << x.peekPrevious().uid << std::endl;

    }

    // 使用STL風格的迭代器遍歷
    QLinkedList<MyStruct>::iterator y;
    for(y=ptr.begin();y!=ptr.end();++y)
    {
        std::cout << (*y).uid << std::endl;
    }

    // STL風格的只讀迭代器
    QLinkedList<MyStruct>::const_iterator z;
    for(z=ptr.constBegin();z!=ptr.constEnd();++z)
    {
        std::cout <<((*z).uname).toStdString().data()<< std::endl;
    }

    // 使用讀寫迭代器: 動態生成列表,每次對二取餘
    QLinkedList<int> Number = {1,2,3,4,5,6,7,8,9,10};
    QMutableLinkedListIterator<int> item(Number);

    // --> 從前向後輸出一次
    for(item.toFront();item.hasNext();item.next())
        std::cout << item.peekNext() << std::endl;

    // --> 將指標移動到最後然後判斷
    for(item.toBack();item.hasPrevious();)
    {
        if(item.previous() % 2==0)
            item.remove();
        else
            item.setValue(item.peekNext() * 10);
    }
    // --> 最後輸出出相加後的結果
    for(item.toFront();item.hasNext();)
    {
        std::cout << item.peekNext() << std::endl;
        item.next();
    }
    return a.exec();
}

1.3 QVector 動態陣列容器

QVector 是Qt中的動態陣列類,它提供了動態大小的陣列,並在內部使用指標陣列進行儲存。QVector 是一個靈活的動態陣列類,適用於需要動態管理元素集合的場景,同時由於其連續儲存的特性,在訪問元素的效率上相對較高。

以下是 QVector 的一些常用函式:

函式 功能
QVector::QVector() 建構函式,建立一個空的 QVector 物件。
QVector::QVector(int size) 建構函式,建立一個包含 size 個元素的 QVector 物件。
QVector::QVector(int size, const T &value) 建構函式,建立一個包含 size 個元素,每個元素都是給定值的 QVector 物件。
QVector::QVector(const QVector &other) 複製建構函式,建立一個與給定向量相同的 QVector 物件。
QVector::append(const T &value) 在向量末尾新增一個元素。
QVector::prepend(const T &value) 在向量開頭新增一個元素。
QVector::replace(int i, const T &value) 替換向量中索引為 i 的元素為給定的值。
QVector::removeAt(int i) 移除向量中索引為 i 的元素。
QVector::removeOne(const T &value) 移除向量中第一個匹配給定值的元素。
QVector::remove(const T &value) 移除向量中所有匹配給定值的元素。
QVector::takeAt(int i) 移除並返回向量中索引為 i 的元素。
QVector::takeFirst() 移除並返回向量中的第一個元素。
QVector::takeLast() 移除並返回向量中的最後一個元素。
QVector::insert(int i, const T &value) 在向量中索引為 i 的位置插入一個元素。
QVector::fill(const T &value, int size = -1) 使用給定值填充向量,如果指定了 size,則填充到指定大小。
QVector::contains(const T &value) const 判斷向量中是否包含給定值。
QVector::count(const T &value) const 統計向量中匹配給定值的元素數量。
QVector::indexOf(const T &value, int from = 0) const 返回給定值在向量中的第一個匹配項的索引,從指定位置 from 開始搜尋。
QVector::lastIndexOf(const T &value, int from = -1) const 返回給定值在向量中的最後一個匹配項的索引,從指定位置 from 開始反向搜尋。
QVector::isEmpty() const 判斷向量是否為空。
QVector::size() const 返回向量中元素的數量。
QVector::clear() 清空向量,移除所有元素。
QVector::resize(int size) 更改向量的大小,如果新大小大於當前大小,會用預設值填充。
QVector::reserve(int size) 預留空間以容納指定數量的元素,可提高插入操作的效能。
QVector::squeeze() 釋放向量佔用的多餘空間。

QVector 提供了類似於 QList 的操作,但由於其底層使用連續儲存,因此在某些情況下效能更高。開發者可以根據具體的需求選擇適合的容器。

1.3.1 主要特點

  1. 動態陣列: QVector 是動態大小的陣列,可以根據需要自動調整大小。
  2. 連續儲存:QLinkedList 不同,QVector 的元素在記憶體中是連續儲存的,這有助於提高訪問效率。
  3. 泛型: QVector 是泛型容器,可以儲存任意型別的資料。
  4. 可變大小: 陣列的大小可以動態改變,元素的插入和刪除操作在末尾和中間都很高效。

1.3.2 如何使用

QVector 在記憶體中儲存連續的資料,類似於 C++ 中的 std::vector。該容器的使用與Qlist完全一致,但讀取效能要比Qlist更高,但在插入時速度最慢。

#include <QCoreApplication>
#include <iostream>
#include <QVector>
#include <QVectorIterator>
#include <QMutableVectorIterator>

struct MyStruct
{
    qint32 uid;
    QString uname;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector<MyStruct> ptr;
    MyStruct str_ptr;

    str_ptr.uid = 1001;
    str_ptr.uname = "admin";
    ptr.append(str_ptr);

    str_ptr.uid = 1002;
    str_ptr.uname = "guest";
    ptr.append(str_ptr);

    // 使用傳統方式遍歷
    for(qint32 x=0;x<ptr.count();x++)
    {
        std::cout << ptr.at(x).uid << std::endl;
        std::cout << ptr[x].uname.toStdString().data() << std::endl;
    }

    // 使用只讀迭代器遍歷: C++ STL寫法
    QVector<MyStruct>::const_iterator item;
    for(item = ptr.begin();item != ptr.end(); ++item)
    {
        std::cout << (*item).uid << std::endl;
        std::cout << (*item).uname.toStdString().data() << std::endl;
    }

    // 使用讀寫迭代器修改: C++ STL寫法
    QVector<MyStruct>::iterator write_item;
    for(write_item = ptr.begin();write_item !=ptr.end();++write_item)
    {
        if((*write_item).uid == 1001)
        {
            (*write_item).uname = "xxxx";
        }
        std::cout << (*write_item).uid << std::endl;
        std::cout << (*write_item).uname.toStdString().data() << std::endl;
    }

    return a.exec();
}

1.3.3 與QList的比較

  • 相似性: QVectorQList 在介面上非常相似,可以使用相同的函式進行元素的訪問、插入和刪除等操作。
  • 效能差異: 由於 QVector 的元素在記憶體中是連續儲存的,因此在順序訪問時,QVector 的效能通常比 QList 更高。但在中間插入元素時,QVector 的效能可能較差,因為需要移動插入點之後的所有元素。
  • 適用場景: QVector 適用於需要頻繁進行順序訪問而較少進行中間插入操作的場景,例如對大量資料進行順序處理的情況。

1.4 QStack 棧容器

QStack 是 Qt 中的棧容器,它提供了棧(LIFO)的資料結構。該容器用於需要滿足後進先出規則的場景,例如在演算法實現中,或者在某些資料處理過程中需要臨時儲存和恢復狀態。

以下是 QStack 的一些常用函式:

函式 功能
QStack::QStack() 建構函式,建立一個空的 QStack 物件。
QStack::QStack(const QStack &other) 複製建構函式,建立一個與給定棧相同的 QStack 物件。
QStack::push(const T &value) 在棧頂壓入一個元素。
QStack::pop() 彈出棧頂的元素。
QStack::top() const 返回棧頂的元素,不彈出。
QStack::isEmpty() const 判斷棧是否為空。
QStack::size() const 返回棧中元素的數量。
QStack::clear() 清空棧,移除所有元素。
QStack::operator=() 過載賦值運算子,將一個棧賦值給另一個棧。
QStack::operator==() 過載相等運算子,判斷兩個棧是否相等。
QStack::operator!=() 過載不等運算子,判斷兩個棧是否不相等。

QStack 是一個後進先出(LIFO)的棧,提供了壓棧、彈棧等基本操作。棧是一種常見的資料結構,可以用於需要遵循後進先出原則的場景,例如遞迴函式呼叫時的儲存函式呼叫資訊等。

1.4.1 主要特點

  1. 棧資料結構: QStack 是棧的實現,它遵循後進先出(Last In, First Out,LIFO)的原則。
  2. 泛型: QStack 是泛型容器,可以儲存任意型別的資料。
  3. 封閉性: QStack 提供的介面限制在棧頂進行插入和刪除操作,不允許在中間或底部插入或刪除元素。

1.4.2 如何使用

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QStack>
#include <QQueue>

struct MyStruct
{
    qint32 uid;
    QString uname;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 定義並彈出QString型別資料
    QStack<QString> stack;

    stack.push("admin");
    stack.push("guest");

    std::cout << (stack.top()).toStdString().data()<<std::endl;
    while(!stack.isEmpty())
    {
        std::cout << (stack.pop()).toStdString().data() << std::endl;
    }

    // 定義並彈出一個結構型別資料
    QStack<MyStruct> struct_stack;
    MyStruct ptr;

    ptr.uid = 1001;
    ptr.uname = "admin";
    struct_stack.push(ptr);

    ptr.uid = 1002;
    ptr.uname = "guest";
    struct_stack.push(ptr);

    // 分別彈出資料並輸出
    while(!struct_stack.isEmpty())
    {
        MyStruct ref;

        ref = struct_stack.pop();
        std::cout << "uid = " << ref.uid << std::endl;
        std::cout << "uname = " << ref.uname.toStdString().data() << std::endl;
    }

    return a.exec();
}

1.5 QQueue 佇列容器

QQueue 是 Qt 中的佇列容器,它提供了佇列(FIFO)的資料結構。QQueue 可以用於需要滿足先進先出規則的場景,例如在任務排程、資料緩衝等應用中。

以下是 QQueue 的一些常用函式:

函式 功能
QQueue::QQueue() 建構函式,建立一個空的 QQueue 物件。
QQueue::QQueue(const QQueue &other) 複製建構函式,建立一個與給定佇列相同的 QQueue 物件。
QQueue::enqueue(const T &value) 在佇列尾部插入一個元素。
QQueue::dequeue() 移除佇列頭部的元素。
QQueue::head() const 返回佇列頭部的元素,不移除。
QQueue::isEmpty() const 判斷佇列是否為空。
QQueue::size() const 返回佇列中元素的數量。
QQueue::clear() 清空佇列,移除所有元素。
QQueue::operator=() 過載賦值運算子,將一個佇列賦值給另一個佇列。
QQueue::operator==() 過載相等運算子,判斷兩個佇列是否相等。
QQueue::operator!=() 過載不等運算子,判斷兩個佇列是否不相等。

QQueue 是一個先進先出(FIFO)的佇列,提供了入隊、出隊等基本操作。佇列常用於需要按照先後順序處理元素的場景,例如任務佇列、訊息佇列等。

1.5.1 主要特點

  1. 佇列資料結構: QQueue 是佇列的實現,它遵循先進先出(First In, First Out,FIFO)的原則。
  2. 泛型: QQueue 是泛型容器,可以儲存任意型別的資料。
  3. 封閉性: QQueue 提供的介面限制在佇列的前端進行插入,佇列的後端進行刪除操作。

1.5.2 如何使用

佇列就是先進後出,在使用上與普通容器保持一致,只是佇列的可用方法會更少一些。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QQueue>

struct MyStruct
{
    qint32 uid;
    QString uname;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QQueue<MyStruct> ptr;
    MyStruct queue_ptr;

    // 實現對結構體的入隊
    queue_ptr.uid = 1001;
    queue_ptr.uname = "admin";
    ptr.enqueue(queue_ptr);

    queue_ptr.uid = 1002;
    queue_ptr.uname = "guest";
    ptr.enqueue(queue_ptr);

    // 實現對結構體的出隊
    while(!ptr.isEmpty())
    {
        MyStruct ref;

        ref = ptr.dequeue();
        std::cout << "uid = " << ref.uid << std::endl;
        std::cout << "uname = " << ref.uname.toStdString().data() << std::endl;
    }

    return a.exec();
}

相關文章