一文总结Qt序列式容器类—QList
文章目录
一、QList简介
在Qt中,QList类是一个提供列表的模板类,在开发中,也是一个较为常用的序列式容器类。
在QList内部,如果sizeof(T) <= sizeof(void *)
并且T已经被声明为Q_MOVABLE_TYPE
或Q_PRIMITIVE_TYPE
(使用Q_DECLARE_TYPEINFO
),那么QList被表示为一个T数组。否则,QList表示为一个T*数组,并且将在堆上分配项。数组表示允许快速的插入和基于索引的访问。prepend()和append()操作也很快,因为QList在其内部数组的两端预先分配了内存。
【注意】如果QList表示为一个T*数组,那么每个新项的追加或插入都需要在堆上分配新项,在这种情况下,QVector比QList更适合做这件事:QVector可以在一个堆分配中为许多项分配内存,这种分配使QVector成为做大量附加或插入操作的最佳选择,所以在此应用场景下QVector是一个很好的选择。
在QList生命周期内,内部数组只会变大,不会减小。当一个列表被分配给另一个列表时,析构函数和赋值操作符才释放QList的内部数组。
二、QList使用方法
(2-1)直接创建QList对象:
QList<int>studentNum;
QList<QDate>dataList;
(2-2)创建并初始化QList对象:
QList<QString>studentNmae = {"iriczhao","xiaoFei","zhangSan"};
三、QList常使用的成员函数
(3-1)向QList中插入项
void QList::insert(int i, const T &value)
insert()
将在列表的索引位置i处插入值。如果i == 0,则该值将会被添加到列表前面。如果i == size(),值将会被追加到列表中。
void QList::append(const T &value)
append()
在列表的末尾插入value。
void QList::prepend(const T &value)
prepend()
在列表的开头插入值。
(3-2)移除QList中的项
int QList::removeAll(const T &value)
removeAll()
删除列表中出现的所有值,并返回删除的条目数。
void QList::removeAt(int i)
removeAt()移除索引位置i的元素。i必须是列表中一个有效的索引位置(即:0 <= i < size())。
void QList::removeFirst()
removeFirst()函数将删除列表中的第一个项。调用该函数相当于调用removeAt(0)。注意:列表不能为空,如果列表可以为空,则在调用此函数之前需调用isEmpty()函数进行判断。
void QList::removeLast()
removeLast()删除列表中的最后一项。调用这个函数相当于调用removeAt(size() - 1)
。注意:列表不能为空。
bool QList::removeOne(const T &value)
removeOne()将移除列表中第一个出现的value。即如果列表中存在多个value,调用该函数将移除第一个value,其余的不受到影响。
(3-3)移动QList中的项
void QList::move(int from, int to)
move()函数作用将位于from索引位置的项从索引移动到to表示的位置。注意:为了移动成功,需确保from和to两个参数值大于0且小于列表的size()大小值;
(3-4)访问QList中的项
const T &QList::at(int i) const
at()函数用于返回列表中索引位置i处的项。i必须是一个有效的索引位置值(即:0 <= i< size())。例如以下代码:
for (int i = 0; i < list.size(); ++i) {
if (list.at(i) == "iriczhao")
cout << "iriczhao position :" << i << Qt::endl;
}
注:该函数比operate[]()
快。
在实际应用中,很多时候需要从列表中删除一个项并对其进行操作。QList提供了takeAt()、takeFirst()和takeLast()成员函数供我们选择。
T QList::takeAt(int i)
tackAt()
函数移除索引位置i的项并返回。i必须是一个有效索引位置。
T QList::takeFirst()
takeFirst()移除列表中的第一项并返回它。该函数和takeAt(0)是一样的。为了避免该函数执行失败,在调用这个函数之前需调用isEmpty()进行检查。
T QList::takeLast()
takeLast()函数将移除列表中的最后一项并返回它。该函数与takeAt(size() - 1)
相同。同样的,为了避免该函数执行失败,在调用这个函数之前需调用isEmpty()进行检查。
(3-5)查找QList中的项
int QList::indexOf(const T &value, int from = 0) const
indexOf()函数返回列表中第一个值出现的索引位置,从from索引位置向前搜索。如果没有匹配项,则返回-1。
int QList::lastIndexOf(const T &value, int from = -1) const
lastIndexOf()函数返回列表中最后一个值出现的索引位置,从索引位置向后搜索。如果from是-1(默认值),则从最后一项开始搜索。如果没有匹配项,则返回-1。
bool QList::contains(const T &value) const
contains()函数用于检查列表中是否包含一个值,如果包含,则返回true;否则返回false;
int QList::count() const
count()函数返回列表中的项数,该函数实际上与size()相同。
int QList::count(const T &value) const
该函数用于检查列表中value出现的次数。注意:此函数要求value的类型实现了operator==()操作!!
四、QList使用注意事项
(4-1)QList的值类型必须是可分配的数据类型。对于Qt来说,这已经涵盖了大多数常见数据类型,但是编译器不允许将QWidget存储为值;所以在开发中,我们可以存储一个指向QWidget的指针QWidget * 。对于QList的少数成员函数还有附加的要求:例如indexOf()和lastIndexOf()传入的参数的值类型支持operate==()操作。
(4-2)QList不支持插入、前置、附加或替换自身值的引用。这样做可能导致应用程序崩溃,并显示错误消息。
(4-3)为了使QList尽可能高效执行,其成员函数在使用之前不验证它们的输入。除了isEmpty(),成员函数总是假定列表不是空的。将索引值作为参数的成员函数总是假设它们的索引值参数在有效范围内。这意味着QList成员函数可能会失败。如果在编译时定义QT_NO_DEBUG,则不会检测到失败。如果没有定义QT_NO_DEBUG,则可以使用Q_ASSERT()或Q_ASSERT_X()和适当的打印消息来检测故障问题。总而言之,就是在使用QList的基于索引的成员函数时,需要使用isEmpty()
函数来判断该QList是否为空,避免传入无效的索引值。
五、结尾
关于QList更多类成员函数的功能和使用方法可参考官方文档:https://doc.qt.io/qt-5/qlist.html#count
本文总结了在实际Qt开发中,常使用到QList类的成员函数以及一些注意事项。