Qt库提供了一组通用的基于模板的容器类。这些类可用于存储指定类型的项。例如,如果你需要一个可调整大小的QString数组,使用QVector
这些容器类被设计成比STL容器更轻、更安全、更容易使用。如果你不熟悉STL,或者更喜欢“Qt方式”,你可以使用这些类而不是STL类。
容器类是隐式共享的,它们是可重入的,并且它们对速度、低内存消耗和最小的内联代码扩展进行了优化,从而产生更小的可执行文件。此外,当所有用于访问它们的线程都将它们用作只读容器时,它们是线程安全的。
为了遍历存储在容器中的项,可以使用两种类型的迭代器之一:java风格的迭代器和stl风格的迭代器。java风格的迭代器更容易使用并提供高级功能,而STL风格的迭代器稍微更高效,可以与Qt和STL的泛型算法一起使用。
Qt还提供了foreach关键字,可以很容易地遍历存储在容器中的所有项。
2.容器类
Qt提供了以下顺序容器:QList、QlinkedList、QVector、QStack和QQueue。对于大多数应用程序,QList是最好的类型。虽然它是作为数组列表实现的,但它提供了非常快的前置和追加。如果你真的需要一个链表,使用QlinkedList;如果你想要你的项目占据连续的内存位置,使用QVector。QStack和QQueue是提供LIFO和FIFO语义的方便类。
Qt还提供了这些关联容器:QMap、QMultiMap、QHash、QMultiHash和QSet。“Multi”容器方便地支持与单个键相关联的多个值。“Hash”容器通过使用哈希函数而不是对排序集进行二分查找,从而提供了更快的查找速度。
在特殊情况下,QCache和QContiguousCache类在有限的缓存存储中提供有效的对象哈希查找。
| Class | 摘要 |
| QList | 这是迄今为止最常用的容器类。它存储了一个可以通过索引访问的给定类型(T)的值列表。在内部,QList是使用数组实现的,确保基于索引的访问非常快。 项目可以使用QList::append()和QList::prepend()添加到列表的任意一端,也可以使用QList::insert()插入到中间。与其他容器类相比,QList经过了高度优化,可以在可执行文件中扩展到尽可能少的代码。QStringList继承自QList |
| QlinkedList | 这类似于QList,不同之处在于它使用迭代器而不是整数索引来访问项。当在一个巨大的列表中间插入时,它还提供了比QList更好的性能,并且它具有更好的迭代器语义。(指向QlinkedList中的项的迭代器只要该项存在就保持有效,而指向QList的迭代器在任何插入或删除后都可能失效。) |
| QVector | 它在内存中相邻位置存储一个给定类型的值数组。在vector的前面或中间插入可能会非常慢,因为这可能会导致大量的项必须在内存中移动一个位置。 |
| QStack | 这是QVector的一个方便的子类,提供了“后进先出”(LIFO)语义。它向QVector中已经存在的函数添加了以下函数:push()、pop()和top()。 |
| QQueue | 这是QList的一个方便的子类,它提供了“先进先出”(FIFO)语义。它将下列函数添加到QList中已经存在的函数中:enqueue()、dequeue()和head()。 |
| QSet | 这提供了一个具有快速查找功能的单值数学集。 |
| QMap | 这提供了一个字典(关联数组),将Key类型的键映射到T类型的值。通常每个键都与单个值相关联。QMap以Key顺序存储数据;如果顺序不重要,QHash是一个更快的选择。 |
| QMultiMap | 这是QMap的一个方便的子类,它为多值映射提供了一个很好的接口,即一个键可以与多个值关联的映射。 |
| QHash | 它具有与QMap几乎相同的API,但提供了快得多的查找。QHash以任意顺序存储数据。 |
| QMultiHash | 这是QHash的一个方便的子类,它为多值哈希提供了一个很好的接口。 |
容器可以嵌套。 例如,完全可以使用QMap
容器定义在与容器同名的单独头文件中(例如,
存储在各种容器中的值可以是任何可分配的数据类型。要进行限定,类型必须提供默认构造函数、复制构造函数和赋值操作符。 这涵盖了您可能想要存储在容器中的大多数数据类型,包括基本类型,如int和double,指针类型,以及Qt数据类型,如QString, QDate和QTime,但它不包括QObject或任何QObject子类(QWidget, QDialog, QTimer,等等)。 如果您试图实例化QList
如果您希望将这些类型的对象存储在容器中,则将它们存储为指针,例如将它们存储为QList
下面是一个自定义数据类型的例子,它满足可赋值数据类型的要求:
class Employee
{
public:
Employee() {}
Employee(const Employee &other);
Employee &operator=(const Employee &other);
private:
QString myName;
QDate myDateOfBirth;
};
如果不提供复制构造函数或赋值操作符,c++会提供一个默认实现来执行成员对成员的复制。 在上面的例子中,这就足够了。 此外,如果不提供任何构造函数,c++提供了一个默认构造函数,该构造函数使用默认构造函数初始化其成员。虽然它没有提供任何显式构造函数或赋值操作符,但以下数据类型可以存储在容器中:
struct Movie
{
int id;
QString title;
QDate releaseDate;
};
有些容器对它们可以存储的数据类型有额外的要求。例如,QMap
QDataStream &operator<<(QDataStream &out, const Movie &movie)
{
out << (quint32)movie.id << movie.title
<< movie.releaseDate;
return out;
}
QDataStream &operator>>(QDataStream &in, Movie &movie)
{
quint32 id;
QDate date;
in >> id >> movie.title >> date;
movie.id = (int)id;
movie.releaseDate = date;
return in;
}
某些容器类函数的文档引用了默认构造的值; 例如,QVector会自动用默认构造的值初始化它的条目,如果指定的键不在映射中,QMap::value()会返回一个默认构造的值。 对于大多数值类型,这仅仅意味着使用默认构造函数(例如QString的空字符串)创建一个值。 但是对于像int和double这样的基本类型,以及指针类型,c++语言没有指定任何初始化; 在这种情况下,Qt的容器会自动将该值初始化为0。
Qt包含三个在某些方面类似于容器的模板类。 这些类不提供迭代器,不能与foreach关键字一起使用。
- QVarLengthArray
提供低级的变长数组。 它可以在速度特别重要的地方代替QVector。 - QCache
提供一个缓存来存储与Key类型的键相关联的特定类型T的对象。 - QContiguousCache
提供一种缓存通常以连续方式访问的数据的有效方法。 - QPair
存储一对元素。
与Qt模板容器竞争的其他非模板类型有QBitArray、QByteArray、QString和QStringList。



