C++ Qt开发:使用顺序容器类
當(dāng)我們談?wù)摼幊讨械臄?shù)據(jù)結(jié)構(gòu)時(shí),順序容器是不可忽視的一個(gè)重要概念。順序容器是一種能夠按照元素添加的順序來存儲(chǔ)和檢索數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。它們提供了簡單而直觀的方式來組織和管理數(shù)據(jù),為程序員提供了靈活性和性能的平衡。
Qt 中提供了豐富的容器類,用于方便地管理和操作數(shù)據(jù)。這些容器類涵蓋了各種不同的用途,從簡單的動(dòng)態(tài)數(shù)組到復(fù)雜的映射和集合。本章我們將主要學(xué)習(xí)順序容器,順序容器是一組強(qiáng)大而靈活的數(shù)據(jù)結(jié)構(gòu),用于按照元素添加的順序存儲(chǔ)和管理數(shù)據(jù)。Qt提供了多種順序容器,每種都具有獨(dú)特的特性,這些容器包括向量、列表、隊(duì)列、棧等,每種都有特定的適用場景。
當(dāng)然了STL標(biāo)準(zhǔn)模板中也存在這些容器,Qt 的容器類與標(biāo)準(zhǔn)模板庫(STL)中的容器類有些相似,但也有一些不同之處。以下是 Qt 容器類相對于STL的一些特點(diǎn)和優(yōu)勢:
-
可自動(dòng)共享數(shù)據(jù):
- Qt 容器類使用了引用計(jì)數(shù)的技術(shù),能夠自動(dòng)共享數(shù)據(jù),減少內(nèi)存占用。當(dāng)一個(gè)容器對象復(fù)制另一個(gè)容器對象時(shí),它們可以共享底層數(shù)據(jù)而不是進(jìn)行深拷貝。
-
隱式共享:
- Qt 容器類通過隱式共享實(shí)現(xiàn)了高效的數(shù)據(jù)共享。只有在發(fā)生寫操作時(shí),才會(huì)執(zhí)行深拷貝,從而減少不必要的開銷。
-
可跨線程使用:
- Qt 容器類支持在多線程環(huán)境中安全使用,通過顯式共享(
QExplicitlySharedDataPointer)和不顯式共享兩種方式,方便在多線程應(yīng)用中進(jìn)行數(shù)據(jù)處理。
- Qt 容器類支持在多線程環(huán)境中安全使用,通過顯式共享(
-
提供了一些額外的功能:
- Qt 的容器類在標(biāo)準(zhǔn)容器的基礎(chǔ)上提供了一些額外的功能,例如對 Unicode 字符串的特殊支持(
QString),以及一些便捷的成員函數(shù),使得容器的使用更為方便。
- Qt 的容器類在標(biāo)準(zhǔn)容器的基礎(chǔ)上提供了一些額外的功能,例如對 Unicode 字符串的特殊支持(
-
內(nèi)存管理:
- Qt 容器類負(fù)責(zé)管理其元素的內(nèi)存,使得內(nèi)存的分配和釋放不需要額外的手動(dòng)管理,減輕了開發(fā)者的負(fù)擔(dān)。
-
直觀的 API 設(shè)計(jì):
- Qt 的容器類 API 設(shè)計(jì)考慮了 Qt 的整體框架,采用了一致而直觀的命名規(guī)范,使得使用者更容易理解和記憶容器類的接口。
-
與其他 Qt 類的集成:
- Qt 容器類能夠無縫地與其他 Qt 類和框架集成,例如與信號和槽機(jī)制一起使用,使得在 Qt 應(yīng)用程序中的開發(fā)更為方便。
在某些特定的場景和需求下,STL 的容器類可能更適合使用。然而,在使用 Qt 框架的情況下,Qt 容器類通常能夠提供更好的集成和一些額外的特性。選擇使用哪種容器類取決于具體的項(xiàng)目需求和開發(fā)者的偏好。
1.1 QList 動(dòng)態(tài)數(shù)組容器
QList 是 Qt 中常用的動(dòng)態(tài)數(shù)組類,它提供了動(dòng)態(tài)大小的數(shù)組,支持在列表的兩端和中間快速插入、刪除元素。適用于需要?jiǎng)討B(tài)管理元素集合的場景,使得對列表的操作更加簡便。
以下是 QList 的一些常用函數(shù):
| 函數(shù) | 功能 |
|---|---|
QList::QList() |
構(gòu)造函數(shù),創(chuàng)建一個(gè)空的 QList 對象。 |
QList::QList(const QList &other) |
復(fù)制構(gòu)造函數(shù),創(chuàng)建一個(gè)與給定列表相同的 QList 對象。 |
QList::append(const T &value) |
在列表末尾添加一個(gè)元素。 |
QList::prepend(const T &value) |
在列表開頭添加一個(gè)元素。 |
QList::replace(int i, const T &value) |
替換列表中索引為 i 的元素為給定的值。 |
QList::removeAt(int i) |
移除列表中索引為 i 的元素。 |
QList::removeOne(const T &value) |
移除列表中第一個(gè)匹配給定值的元素。 |
QList::removeAll(const T &value) |
移除列表中所有匹配給定值的元素。 |
QList::takeAt(int i) |
移除并返回列表中索引為 i 的元素。 |
QList::takeFirst() |
移除并返回列表中的第一個(gè)元素。 |
QList::takeLast() |
移除并返回列表中的最后一個(gè)元素。 |
QList::insert(int i, const T &value) |
在列表中索引為 i 的位置插入一個(gè)元素。 |
QList::contains(const T &value) const |
判斷列表中是否包含給定值。 |
QList::count(const T &value) const |
統(tǒng)計(jì)列表中匹配給定值的元素?cái)?shù)量。 |
QList::indexOf(const T &value, int from = 0) const |
返回給定值在列表中的第一個(gè)匹配項(xiàng)的索引,從指定位置 from 開始搜索。 |
QList::lastIndexOf(const T &value, int from = -1) const |
返回給定值在列表中的最后一個(gè)匹配項(xiàng)的索引,從指定位置 from 開始反向搜索。 |
QList::isEmpty() const |
判斷列表是否為空。 |
QList::size() const |
返回列表中元素的數(shù)量。 |
QList::clear() |
清空列表,移除所有元素。 |
QList::operator=() |
重載賦值運(yùn)算符,將一個(gè)列表賦值給另一個(gè)列表。 |
QList::operator==() |
重載相等運(yùn)算符,判斷兩個(gè)列表是否相等。 |
QList::operator!=() |
重載不等運(yùn)算符,判斷兩個(gè)列表是否不相等。 |
以上是 QList 的一些常用函數(shù)及其功能,這些函數(shù)允許開發(fā)者對列表進(jìn)行添加、刪除、替換、查找等操作,以滿足不同場景的需求。
1.1.1 主要特點(diǎn)
-
動(dòng)態(tài)數(shù)組:
QList是動(dòng)態(tài)大小的數(shù)組,可以根據(jù)需要自動(dòng)調(diào)整大小。 -
泛型:
QList是泛型容器,可以存儲(chǔ)任意類型的數(shù)據(jù)。 - 可變大小: 列表的大小可以動(dòng)態(tài)改變,元素的插入和刪除操作都很高效。
-
雙向迭代器:
QList提供了雙向迭代器,可以方便地從前往后或從后往前遍歷列表。
1.1.2 如何使用
如下所示的代碼中我定義了兩個(gè)QList容器,分別是StringPtrA和StringPtrB通過使用不同的容器操作函數(shù)對其進(jìn)行簡單的增加插入替換刪除和移動(dòng)操作,如下代碼所示;
#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;
// 添加三個(gè)成員
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個(gè)元素
StringPtrA.removeAt(0);
Display(StringPtrA);
// 刪除首部和尾部
StringPtrA.removeFirst();
StringPtrA.removeLast();
// 移動(dòng)兩個(gè)變量
StringPtrA.move(0,1);
Display(StringPtrA);
// 將兩個(gè)list容器對調(diào)交換
StringPtrB = {"youtube","facebook"};
StringPtrA.swap(StringPtrB);
Display(StringPtrA);
return a.exec();
}
上述代碼我們只是對字符串進(jìn)行了鏈表管理,其實(shí)Qt中支持管理結(jié)構(gòu)體,首先要定義一個(gè)特有的結(jié)構(gòu)體MyStruct當(dāng)結(jié)構(gòu)體被賦值后就可以像數(shù)組一樣靈活的操作數(shù)據(jù),當(dāng)然在使用結(jié)構(gòu)體時(shí)我們傳入的應(yīng)該是QList<MyStruct>結(jié)構(gòu)體的名字,在遍歷時(shí)可以有三種方式,第一種時(shí)傳統(tǒng)的循環(huán)依次輸出元素,這里我們說說使用QListIterator和QMutableListIterator來輸出元素的區(qū)別。
#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);
// 使用傳統(tǒng)方式遍歷數(shù)據(jù)
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讀取下一個(gè)節(jié)點(diǎn),但不影響指針變化
std::cout << x.peekNext().uid << std::endl;
std::cout << (x.peekNext().uname).toStdString().data() << std::endl;
// 最后將x指針指向下一個(gè)數(shù)據(jù)
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();
}
其實(shí)QListIterator 和 QMutableListIterator 都是用于遍歷 QList 容器的迭代器類。區(qū)別是QListIterator 是一個(gè)只讀迭代器,用于遍歷 QList 容器中的元素。它提供了一個(gè)方便的方式來訪問容器中的元素,支持前向和后向遍歷。而QMutableListIterator 是一個(gè)可變迭代器,除了支持讀取元素外,還允許修改 QList 中的元素。它提供了修改元素的接口,使得在遍歷的同時(shí)可以對容器進(jìn)行修改。
QListIterator 主要函數(shù)和特點(diǎn)
-
QListIterator(const QList<T> &list): 構(gòu)造函數(shù),用于初始化迭代器并關(guān)聯(lián)到給定的QList。 -
hasNext() const: 檢查是否有下一個(gè)元素。 -
next(): 返回當(dāng)前元素并將迭代器移動(dòng)到下一個(gè)元素。 -
peekNext() const: 返回當(dāng)前元素但不移動(dòng)迭代器。 -
toFront(): 將迭代器移動(dòng)到列表的第一個(gè)元素。 -
toBack(): 將迭代器移動(dòng)到列表的最后一個(gè)元素。
QMutableListIterator 主要函數(shù)和特點(diǎn)
-
QMutableListIterator(QList<T> &list): 構(gòu)造函數(shù),用于初始化可變迭代器并關(guān)聯(lián)到給定的QList。 -
hasNext() const: 檢查是否有下一個(gè)元素。 -
next(): 返回當(dāng)前元素并將迭代器移動(dòng)到下一個(gè)元素。 -
peekNext() const: 返回當(dāng)前元素但不移動(dòng)迭代器。 -
toFront(): 將迭代器移動(dòng)到列表的第一個(gè)元素。 -
toBack(): 將迭代器移動(dòng)到列表的最后一個(gè)元素。 -
remove(): 移除迭代器當(dāng)前位置的元素。 -
setValue(const T &value): 將迭代器當(dāng)前位置的元素設(shè)置為給定值。
這兩個(gè)迭代器類提供了方便而靈活的方式來遍歷和操作 QList 中的元素,根據(jù)需要選擇合適的迭代器。
1.2 QLinkeList 雙向鏈表容器
QLinkedList 是 Qt 中的雙向鏈表實(shí)現(xiàn),與 QList 不同,它不是基于數(shù)組的動(dòng)態(tài)容器,而是基于鏈表的數(shù)據(jù)結(jié)構(gòu)。QLinkedList 提供了鏈表特有的靈活性,適用于需要在任意位置高效插入和刪除元素的場景。在一些訪問元素的場景中,由于鏈表的非連續(xù)存儲(chǔ)特性,可能比數(shù)組容器的訪問效率稍低。選擇使用 QLinkedList 還是其他容器,取決于具體的使用需求。
以下是 QLinkedList 的一些常用函數(shù):
| 函數(shù) | 功能 |
|---|---|
QLinkedList::QLinkedList() |
構(gòu)造函數(shù),創(chuàng)建一個(gè)空的 QLinkedList 對象。 |
QLinkedList::QLinkedList(const QLinkedList &other) |
復(fù)制構(gòu)造函數(shù),創(chuàng)建一個(gè)與給定鏈表相同的 QLinkedList 對象。 |
QLinkedList::append(const T &value) |
在鏈表末尾添加一個(gè)元素。 |
QLinkedList::prepend(const T &value) |
在鏈表開頭添加一個(gè)元素。 |
QLinkedList::replace(const_iterator before, const T &value) |
替換鏈表中給定迭代器位置的元素為給定的值。 |
QLinkedList::remove(const T &value) |
移除鏈表中所有匹配給定值的元素。 |
QLinkedList::removeOne(const T &value) |
移除鏈表中第一個(gè)匹配給定值的元素。 |
QLinkedList::removeAt(int i) |
移除鏈表中索引為 i 的元素。 |
QLinkedList::takeAt(int i) |
移除并返回鏈表中索引為 i 的元素。 |
QLinkedList::takeFirst() |
移除并返回鏈表中的第一個(gè)元素。 |
QLinkedList::takeLast() |
移除并返回鏈表中的最后一個(gè)元素。 |
QLinkedList::insert(const_iterator before, const T &value) |
在鏈表中給定迭代器位置插入一個(gè)元素。 |
QLinkedList::contains(const T &value) const |
判斷鏈表中是否包含給定值。 |
QLinkedList::count(const T &value) const |
統(tǒng)計(jì)鏈表中匹配給定值的元素?cái)?shù)量。 |
QLinkedList::indexOf(const T &value) const |
返回給定值在鏈表中的第一個(gè)匹配項(xiàng)的索引。 |
QLinkedList::lastIndexOf(const T &value) const |
返回給定值在鏈表中的最后一個(gè)匹配項(xiàng)的索引。 |
QLinkedList::isEmpty() const |
判斷鏈表是否為空。 |
QLinkedList::size() const |
返回鏈表中元素的數(shù)量。 |
QLinkedList::clear() |
清空鏈表,移除所有元素。 |
QLinkedList::begin() |
返回指向鏈表第一個(gè)元素的迭代器。 |
QLinkedList::end() |
返回指向鏈表最后一個(gè)元素之后的迭代器。 |
QLinkedList 提供了與 QList 類似的操作,但由于其基于雙向鏈表實(shí)現(xiàn),特別適合于需要頻繁插入和刪除操作的場景。在使用上,QLinkedList 提供了一些額外的函數(shù),如 replace、insert 等,可以更方便地操作鏈表中的元素。
1.2.1 主要特點(diǎn)
-
雙向鏈表:
QLinkedList使用雙向鏈表結(jié)構(gòu),每個(gè)節(jié)點(diǎn)存儲(chǔ)一個(gè)元素以及指向前后節(jié)點(diǎn)的指針,支持高效的插入和刪除操作。 -
泛型:
QLinkedList是泛型容器,可以存儲(chǔ)任意類型的數(shù)據(jù)。 - 可變大小: 鏈表的大小可以動(dòng)態(tài)改變,元素的插入和刪除操作在任意位置都很高效。
-
雙向迭代器:
QLinkedList提供了雙向迭代器,可以方便地從前往后或從后往前遍歷鏈表。
1.2.2 如何使用
QLinkeList其實(shí)就是動(dòng)態(tài)鏈表結(jié)構(gòu),數(shù)據(jù)的存儲(chǔ)非連續(xù),訪問時(shí)無法直接使用下標(biāo)定位,只能通過迭代器迭代尋找,這是其與QList的本質(zhì)區(qū)別,其參數(shù)定義與QList基本一致,在使用上并沒有本質(zhì)上的區(qū)別。
#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風(fēng)格的迭代器遍歷
QLinkedList<MyStruct>::iterator y;
for(y=ptr.begin();y!=ptr.end();++y)
{
std::cout << (*y).uid << std::endl;
}
// STL風(fēng)格的只讀迭代器
QLinkedList<MyStruct>::const_iterator z;
for(z=ptr.constBegin();z!=ptr.constEnd();++z)
{
std::cout <<((*z).uname).toStdString().data()<< std::endl;
}
// 使用讀寫迭代器: 動(dòng)態(tài)生成列表,每次對二取余
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;
// --> 將指針移動(dòng)到最后然后判斷
for(item.toBack();item.hasPrevious();)
{
if(item.previous() % 2==0)
item.remove();
else
item.setValue(item.peekNext() * 10);
}
// --> 最后輸出出相加后的結(jié)果
for(item.toFront();item.hasNext();)
{
std::cout << item.peekNext() << std::endl;
item.next();
}
return a.exec();
}
1.3 QVector 動(dòng)態(tài)數(shù)組容器
QVector 是Qt中的動(dòng)態(tài)數(shù)組類,它提供了動(dòng)態(tài)大小的數(shù)組,并在內(nèi)部使用指針數(shù)組進(jìn)行存儲(chǔ)。QVector 是一個(gè)靈活的動(dòng)態(tài)數(shù)組類,適用于需要?jiǎng)討B(tài)管理元素集合的場景,同時(shí)由于其連續(xù)存儲(chǔ)的特性,在訪問元素的效率上相對較高。
以下是 QVector 的一些常用函數(shù):
| 函數(shù) | 功能 |
|---|---|
QVector::QVector() |
構(gòu)造函數(shù),創(chuàng)建一個(gè)空的 QVector 對象。 |
QVector::QVector(int size) |
構(gòu)造函數(shù),創(chuàng)建一個(gè)包含 size 個(gè)元素的 QVector 對象。 |
QVector::QVector(int size, const T &value) |
構(gòu)造函數(shù),創(chuàng)建一個(gè)包含 size 個(gè)元素,每個(gè)元素都是給定值的 QVector 對象。 |
QVector::QVector(const QVector &other) |
復(fù)制構(gòu)造函數(shù),創(chuàng)建一個(gè)與給定向量相同的 QVector 對象。 |
QVector::append(const T &value) |
在向量末尾添加一個(gè)元素。 |
QVector::prepend(const T &value) |
在向量開頭添加一個(gè)元素。 |
QVector::replace(int i, const T &value) |
替換向量中索引為 i 的元素為給定的值。 |
QVector::removeAt(int i) |
移除向量中索引為 i 的元素。 |
QVector::removeOne(const T &value) |
移除向量中第一個(gè)匹配給定值的元素。 |
QVector::remove(const T &value) |
移除向量中所有匹配給定值的元素。 |
QVector::takeAt(int i) |
移除并返回向量中索引為 i 的元素。 |
QVector::takeFirst() |
移除并返回向量中的第一個(gè)元素。 |
QVector::takeLast() |
移除并返回向量中的最后一個(gè)元素。 |
QVector::insert(int i, const T &value) |
在向量中索引為 i 的位置插入一個(gè)元素。 |
QVector::fill(const T &value, int size = -1) |
使用給定值填充向量,如果指定了 size,則填充到指定大小。 |
QVector::contains(const T &value) const |
判斷向量中是否包含給定值。 |
QVector::count(const T &value) const |
統(tǒng)計(jì)向量中匹配給定值的元素?cái)?shù)量。 |
QVector::indexOf(const T &value, int from = 0) const |
返回給定值在向量中的第一個(gè)匹配項(xiàng)的索引,從指定位置 from 開始搜索。 |
QVector::lastIndexOf(const T &value, int from = -1) const |
返回給定值在向量中的最后一個(gè)匹配項(xiàng)的索引,從指定位置 from 開始反向搜索。 |
QVector::isEmpty() const |
判斷向量是否為空。 |
QVector::size() const |
返回向量中元素的數(shù)量。 |
QVector::clear() |
清空向量,移除所有元素。 |
QVector::resize(int size) |
更改向量的大小,如果新大小大于當(dāng)前大小,會(huì)用默認(rèn)值填充。 |
QVector::reserve(int size) |
預(yù)留空間以容納指定數(shù)量的元素,可提高插入操作的性能。 |
QVector::squeeze() |
釋放向量占用的多余空間。 |
QVector 提供了類似于 QList 的操作,但由于其底層使用連續(xù)存儲(chǔ),因此在某些情況下性能更高。開發(fā)者可以根據(jù)具體的需求選擇適合的容器。
1.3.1 主要特點(diǎn)
-
動(dòng)態(tài)數(shù)組:
QVector是動(dòng)態(tài)大小的數(shù)組,可以根據(jù)需要自動(dòng)調(diào)整大小。 -
連續(xù)存儲(chǔ): 與
QLinkedList不同,QVector的元素在內(nèi)存中是連續(xù)存儲(chǔ)的,這有助于提高訪問效率。 -
泛型:
QVector是泛型容器,可以存儲(chǔ)任意類型的數(shù)據(jù)。 - 可變大小: 數(shù)組的大小可以動(dòng)態(tài)改變,元素的插入和刪除操作在末尾和中間都很高效。
1.3.2 如何使用
QVector 在內(nèi)存中存儲(chǔ)連續(xù)的數(shù)據(jù),類似于 C++ 中的 std::vector。該容器的使用與Qlist完全一致,但讀取性能要比Qlist更高,但在插入時(shí)速度最慢。
#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);
// 使用傳統(tǒng)方式遍歷
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的比較
-
相似性:
QVector和QList在接口上非常相似,可以使用相同的函數(shù)進(jìn)行元素的訪問、插入和刪除等操作。 -
性能差異: 由于
QVector的元素在內(nèi)存中是連續(xù)存儲(chǔ)的,因此在順序訪問時(shí),QVector的性能通常比QList更高。但在中間插入元素時(shí),QVector的性能可能較差,因?yàn)樾枰苿?dòng)插入點(diǎn)之后的所有元素。 -
適用場景:
QVector適用于需要頻繁進(jìn)行順序訪問而較少進(jìn)行中間插入操作的場景,例如對大量數(shù)據(jù)進(jìn)行順序處理的情況。
1.4 QStack 棧容器
QStack 是 Qt 中的棧容器,它提供了棧(LIFO)的數(shù)據(jù)結(jié)構(gòu)。該容器用于需要滿足后進(jìn)先出規(guī)則的場景,例如在算法實(shí)現(xiàn)中,或者在某些數(shù)據(jù)處理過程中需要臨時(shí)存儲(chǔ)和恢復(fù)狀態(tài)。
以下是 QStack 的一些常用函數(shù):
| 函數(shù) | 功能 |
|---|---|
QStack::QStack() |
構(gòu)造函數(shù),創(chuàng)建一個(gè)空的 QStack 對象。 |
QStack::QStack(const QStack &other) |
復(fù)制構(gòu)造函數(shù),創(chuàng)建一個(gè)與給定棧相同的 QStack 對象。 |
QStack::push(const T &value) |
在棧頂壓入一個(gè)元素。 |
QStack::pop() |
彈出棧頂?shù)脑亍?/td> |
QStack::top() const |
返回棧頂?shù)脑兀粡棾觥?/td> |
QStack::isEmpty() const |
判斷棧是否為空。 |
QStack::size() const |
返回棧中元素的數(shù)量。 |
QStack::clear() |
清空棧,移除所有元素。 |
QStack::operator=() |
重載賦值運(yùn)算符,將一個(gè)棧賦值給另一個(gè)棧。 |
QStack::operator==() |
重載相等運(yùn)算符,判斷兩個(gè)棧是否相等。 |
QStack::operator!=() |
重載不等運(yùn)算符,判斷兩個(gè)棧是否不相等。 |
QStack 是一個(gè)后進(jìn)先出(LIFO)的棧,提供了壓棧、彈棧等基本操作。棧是一種常見的數(shù)據(jù)結(jié)構(gòu),可以用于需要遵循后進(jìn)先出原則的場景,例如遞歸函數(shù)調(diào)用時(shí)的存儲(chǔ)函數(shù)調(diào)用信息等。
1.4.1 主要特點(diǎn)
-
棧數(shù)據(jù)結(jié)構(gòu):
QStack是棧的實(shí)現(xiàn),它遵循后進(jìn)先出(Last In, First Out,LIFO)的原則。 -
泛型:
QStack是泛型容器,可以存儲(chǔ)任意類型的數(shù)據(jù)。 -
封閉性:
QStack提供的接口限制在棧頂進(jìn)行插入和刪除操作,不允許在中間或底部插入或刪除元素。
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類型數(shù)據(jù)
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;
}
// 定義并彈出一個(gè)結(jié)構(gòu)類型數(shù)據(jù)
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);
// 分別彈出數(shù)據(jù)并輸出
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 隊(duì)列容器
QQueue 是 Qt 中的隊(duì)列容器,它提供了隊(duì)列(FIFO)的數(shù)據(jù)結(jié)構(gòu)。QQueue 可以用于需要滿足先進(jìn)先出規(guī)則的場景,例如在任務(wù)調(diào)度、數(shù)據(jù)緩沖等應(yīng)用中。
以下是 QQueue 的一些常用函數(shù):
| 函數(shù) | 功能 |
|---|---|
QQueue::QQueue() |
構(gòu)造函數(shù),創(chuàng)建一個(gè)空的 QQueue 對象。 |
QQueue::QQueue(const QQueue &other) |
復(fù)制構(gòu)造函數(shù),創(chuàng)建一個(gè)與給定隊(duì)列相同的 QQueue 對象。 |
QQueue::enqueue(const T &value) |
在隊(duì)列尾部插入一個(gè)元素。 |
QQueue::dequeue() |
移除隊(duì)列頭部的元素。 |
QQueue::head() const |
返回隊(duì)列頭部的元素,不移除。 |
QQueue::isEmpty() const |
判斷隊(duì)列是否為空。 |
QQueue::size() const |
返回隊(duì)列中元素的數(shù)量。 |
QQueue::clear() |
清空隊(duì)列,移除所有元素。 |
QQueue::operator=() |
重載賦值運(yùn)算符,將一個(gè)隊(duì)列賦值給另一個(gè)隊(duì)列。 |
QQueue::operator==() |
重載相等運(yùn)算符,判斷兩個(gè)隊(duì)列是否相等。 |
QQueue::operator!=() |
重載不等運(yùn)算符,判斷兩個(gè)隊(duì)列是否不相等。 |
QQueue 是一個(gè)先進(jìn)先出(FIFO)的隊(duì)列,提供了入隊(duì)、出隊(duì)等基本操作。隊(duì)列常用于需要按照先后順序處理元素的場景,例如任務(wù)隊(duì)列、消息隊(duì)列等。
1.5.1 主要特點(diǎn)
-
隊(duì)列數(shù)據(jù)結(jié)構(gòu):
QQueue是隊(duì)列的實(shí)現(xiàn),它遵循先進(jìn)先出(First In, First Out,F(xiàn)IFO)的原則。 -
泛型:
QQueue是泛型容器,可以存儲(chǔ)任意類型的數(shù)據(jù)。 -
封閉性:
QQueue提供的接口限制在隊(duì)列的前端進(jìn)行插入,隊(duì)列的后端進(jìn)行刪除操作。
1.5.2 如何使用
隊(duì)列就是先進(jìn)后出,在使用上與普通容器保持一致,只是隊(duì)列的可用方法會(huì)更少一些。
#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;
// 實(shí)現(xiàn)對結(jié)構(gòu)體的入隊(duì)
queue_ptr.uid = 1001;
queue_ptr.uname = "admin";
ptr.enqueue(queue_ptr);
queue_ptr.uid = 1002;
queue_ptr.uname = "guest";
ptr.enqueue(queue_ptr);
// 實(shí)現(xiàn)對結(jié)構(gòu)體的出隊(duì)
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();
}
總結(jié)
以上是生活随笔為你收集整理的C++ Qt开发:使用顺序容器类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iPhone可以换屏吗?iPhone换屏
- 下一篇: 【UniApp】-uni-app-Opt