Qt容器:QList
一、描述QList<T> 是 Qt 的通用容器类之一。它将其项目存储在相邻的内存位置并提供基于索引的快速访问。QVector<T> 在 Qt 5 中曾经是一个不同的类,但在Qt6它是 QList 的一个别名。QList<T> 和 QVarLengthArray<T> 提供类似的 API 和功能。它们通常可以互换。QList 应该是默认首选。QVarL
一、描述
QList<T> 是 Qt 的通用容器类之一。它将其项目存储在相邻的内存位置并提供基于索引的快速访问。QVector<T> 在 Qt 5 中曾经是一个不同的类,但在Qt6它是 QList 的一个别名。
QList<T> 和 QVarLengthArray<T> 提供类似的 API 和功能。它们通常可以互换。
- QList 应该是默认首选。
- QVarLengthArray 提供了一个在堆栈上保留空间的数组,但如果需要,可以动态地增长到堆上。用于通常较小的短寿命容器是很好的。
由于隐式共享,使用非常量运算符和函数可能会导致 QList 对数据进行深度复制。
QList 的值类型必须是可赋值的数据类型。这涵盖了大多数常用的数据类型,但编译器不会允许将 QWidget 存储为值(可以存储一个 QWidget *)。
最大大小
QList 的最大大小取决于体系结构。大多数 64 位系统可以分配超过 2 GB 的内存,典型限制为 2^63 字节。实际值还取决于管理数据块所需的开销。因此,可以预期最大大小为 2 GB 减去 32 位平台上的开销,以及 2^63 字节减去 64 位平台上的开销。可以存储在 QList 中的元素数是此最大大小除以存储元素的大小。
内存不足的情况
当内存分配失败时,QList 使用 Q_CHECK_PTR 宏,如果应用程序编译时带有异常支持,它会抛出 std::bad_alloc 异常。如果异常被禁用,则内存不足是未定义的行为。
操作系统可能会对持有大量已分配内存的应用程序施加进一步限制,尤其是大的连续块。此类考虑、此类行为的配置或任何缓解措施超出了 Qt API 的范围。
二、成员函数
1、void replace(qsizetype i, QList::parameter_type value)
void replace(qsizetype i, QList::rvalue_ref value)
用值替换索引位置 i 处的项目。i 必须是列表中的有效索引位置(即 0 <= i < size())。
2、插入数据
QList::iterator insert(qsizetype i, QList::parameter_type value)
QList::iterator insert(qsizetype i, QList::rvalue_ref value)
在列表中的索引位置 i 处插入值。 如果 i = 0,则该值将添加到最前面。如果 i = size(),则将该值追加到列表中。
对于大型列表,此操作可能很慢,因为它需要将索引 i 及以上的所有项目在内存中进一步移动一个位置。 如果想要一个提供快速 insert() 函数的容器类,请改用 std::list。
QList::iterator insert(qsizetype i, qsizetype count, QList::parameter_type value)
在列表中的索引位置 i 处插入值的 count 个副本。
QList<double> list;
list << 2.718 << 1.442 << 0.4342;
list.insert(1, 3, 9.9);
// list: [2.718, 9.9, 9.9, 9.9, 1.442, 0.4342]
QList::iterator insert(QList::const_iterator before, QList::parameter_type value)
QList::iterator insert(QList::const_iterator before, QList::rvalue_ref value)
重载函数。在之前的迭代器指向的项目前插入值。返回指向插入项的迭代器。
QList<int> list;
auto insertIt = std::back_inserter(list);
for(int i = 0;i < 7;++i)
{
*insertIt = i;
++insertIt;
}
qDebug()<<list;
auto it = list.begin();
it += 3;
qDebug()<<*it;
auto it2 = list.insert(it,8);
qDebug()<<list;
qDebug()<<*it2;
QList::iterator insert(QList::const_iterator before, qsizetype count, QList::parameter_type value)
在迭代器之前指向的项之前插入值的 count 个副本。 返回指向第一个插入项的迭代器。
3、template <typename Args> QList::reference emplaceBack(Args &&... args)
template <typename Args> QList::reference emplace_back(Args &&... args)
在容器的末尾添加一个新元素。这个新元素是使用 args 作为构造参数就地构造的。返回对新元素的引用。
QList<QString> list{"one", "two"};
list.emplaceBack(3, 'a'); //构造函数:QString(qsizetype size, QChar ch)
qDebug() << list; // list: ["one", "two", "aaa"]
也可以使用返回的引用访问新创建的对象:
QList<QString> list;
auto &ref = list.emplaceBack();
ref = "one";
// list: ["one"]
4、void prepend(QList::parameter_type value)
void prepend(QList::rvalue_ref value)
void push_front(QList::parameter_type value)
void push_front(QList::rvalue_ref value)
在列表的开头插入值。
通常这个操作是比较快的。 QList 能够在列表数据的开头分配额外的内存并在该方向上增长,而无需在每个操作上重新分配或移动数据。 但是,如果想要一个在前面插入复杂度为O(1)的容器类,请改用 std::list。
5、构造函数
QList()
QList(const QList<T> &other)
复杂度为O(1),因为 QList 是隐式共享的。 这使得从函数返回 QList 的速度非常快。 如果共享实例被修改,它将被复制(写时复制),这需要线性时间(O(n))。
QList(QList<T> &&other)
QList(InputIterator first, InputIterator last)
使用迭代器构造。
QList(std::initializer_list<T> args)
QList(qsizetype size, QList::parameter_type value)
构造一个初始大小为 size 元素的列表。每个元素都用value初始化。
QList(qsizetype size)
构造一个初始大小为 size 元素的列表。元素使用默认构造的值进行初始化。
6、在末尾追加元素
void append(QList::parameter_type value)
此操作相对较快,因为 QList 通常分配比所需更多的内存,因此它可以增长而无需每次重新分配整个列表。
void append(QList::rvalue_ref value)
QList<QString> list;
list.append("one");
list.append("two");
QString three = "three";
list.append(std::move(three));
// list: ["one", "two", "three"]
// three: ""
void append(const QList<T> &value)
void append(QList<T> &&value)
void push_back(QList::parameter_type value)
void push_back(QList::rvalue_ref value)
QList<T> & operator+=()
7、QList::const_reference at(qsizetype i) const
QList::const_reference operator[](qsizetype i) const
不会深拷贝。
QList::reference operator[](qsizetype i)
使用非常量运算符会导致 QList 进行深拷贝。
8、 begin() / cbegin() constBegin() / constEnd() end() / cend()
起始迭代器 / 常起始迭代器 尾迭代器 / 常尾迭代器。
crbegin() / crend()
反向迭代器。
QList<int> list;
list << 1<<2<<3;
for(auto it = list.crbegin();it != list.crend();++it)
qDebug()<<(*it);// 3 2 1
9、qsizetype capacity()
返回可以存储在列表中而不强制重新分配的最大项目数。
此函数的唯一目的是提供一种微调 QList 内存使用的方法。通常很少需要调用此函数。如果想知道列表中有多少项应调用 size()。
10、void clear()
从列表中删除所有元素。但列表申请的内存还在。
QList<ceshi> list;
list << 1<<2<<3;
qDebug()<<list.capacity();
list.clear();
qDebug()<<list.capacity();
11、QList::const_pointer constData()
返回指向存储在列表中的数据的常量指针。指针可用于访问列表中的项目。
此函数主要用于将列表传递给接受普通 C++ 数组的函数。
12、const T & constFirst() / const T & constLast()
返回对列表中第一项 / 最后一项的常引用。
13、template <typename AT> bool contains(const AT &value)
是否包含值。此函数要求值类型具有 operator==() 的实现。
14、template <typename AT> qsizetype count(const AT &value)
返回值在列表中出现的次数。此函数要求值类型具有 operator==() 的实现。
15、data()
返回指向存储在列表中的数据的指针。
此函数主要用于将列表传递给接受普通 C++ 数组的函数。
QList<int> list(10);
int *data = list.data();
for (qsizetype i = 0; i < 10; ++i)
data[i] = 2 * i;
16、template <typename Args> QList::iterator emplace(qsizetype i, Args &&... args)
template <typename Args> QList::iterator emplace(QList::const_iterator before, Args &&... args)
在位置 i 插入一个新元素。这个新元素是使用 args 作为构造参数就地构造的。
返回一个指向新元素的迭代器。
QList<QString> list{"a", "ccc"};
list.emplace(1, 2, 'b');
// list: ["a", "bb", "ccc"]
17、bool empty()
提供此功能是为了兼容 STL。等价于isEmpty()。
18、bool endsWith(QList::parameter_type value) / bool startsWith(QList::parameter_type value)
此列表是否不为空且其最后一项 / 第一项 等于 value。
19、 QList::iterator erase(QList::const_iterator pos)
QList::iterator erase(QList::const_iterator begin, QList::const_iterator end)
从列表中移除迭代器 pos 指向的项目,并返回一个迭代器到列表中的下一个项目。
元素删除但未减少列表内存。
20、QList<T> & fill(QList::parameter_type value, qsizetype size = -1)
为列表中的所有项目赋值。 如果 size 不同于 -1(默认值),则列表会预先调整为 size。
QList<QString> list(3);
list.fill("Yes");
// list: ["Yes", "Yes", "Yes"]
list.fill("oh", 5);
// list: ["oh", "oh", "oh", "oh", "oh"]
21、first()、front() / last()、back()
首个元素 / 最后一个元素。
22、QList<T> first(qsizetype n) / QList<T> last(qsizetype n)
返回包含此列表的前 n 个 / 后 n 个元素的子列表。
23、template <typename AT> qsizetype indexOf(const AT &value, qsizetype from = 0)
返回列表中第一次出现 value 的索引位置,从索引位置开始向前搜索。如果没有匹配项,则返回 -1。此函数要求值类型具有 operator==() 的实现。
QList<QString> list;
list << "A" << "B" << "C" << "B" << "A";
list.indexOf("B"); // returns 1
list.indexOf("B", 1); // returns 1
list.indexOf("B", 2); // returns 3
list.indexOf("X"); // returns -1
24、template <typename AT> qsizetype lastIndexOf(const AT &value, qsizetype from = -1)
返回列表中最后一次出现值的索引位置,从索引位置开始向后搜索。如果 from 是 -1(默认值),则搜索从最后一项开始。 如果没有匹配项,则返回 -1。此函数要求值类型具有 operator==() 的实现。
QList<QString> list;
list << "A" << "B" << "C" << "B" << "A";
list.lastIndexOf("B"); // returns 3
list.lastIndexOf("B", 3); // returns 3
list.lastIndexOf("B", 2); // returns 1
list.lastIndexOf("X"); // returns -1
25、QList<T> mid(qsizetype pos, qsizetype length = -1)
返回包含此列表中元素的子列表,从位置 pos 开始。 如果 length 为 -1(默认),则包含 pos 之后的所有元素; 否则包括 length 个元素(如果少于length个元素,则返回所有剩余元素)。
26、void move(qsizetype A, qsizetype B)
将A位置的元素移动到B位置。
27、void pop_back() / void removeLast()
删除列表中的最后一项,但未清理列表的空间。
28、void pop_front() / void removeFirst()
删除列表中的第一项,但未清理列表的空间。
29、void remove(qsizetype i, qsizetype n = 1)
从列表中移除 n 个元素,从索引位置 i 开始。但未清理列表的空间。
30、template <typename AT> qsizetype removeAll(const AT &t)
从列表中删除所有与 t 相等的元素。 返回删除的元素数。但未清理列表的空间。
31、void removeAt(qsizetype i)
等同于:remove(i);
32、template <typename Predicate> qsizetype removeIf(Predicate pred)
从列表中删除谓词 pred 为其返回 true 的所有元素。返回删除的元素数(如果有)。(删除返回某条件的元素)
QList<int> list;
list << 1<<2<<3<<4<<5<<6<<7<<8<<9;
list.swapItemsAt(3,5);
list.removeIf([](const int & value)
{
return value > 3;
});
qDebug()<<list;
33、template <typename AT> bool removeOne(const AT &t)
从列表中删除与 t 相同的第一个元素。返回元素是否实际上已被删除。
34、void reserve(qsizetype size)
尝试为至少 size 个元素分配内存。
如果事先知道列表有多大,则应调用此函数以防止重新分配和内存碎片。
reserve() 保留内存但不改变列表的大小。所以应配合调用 resize()。
35、void resize(qsizetype size)
将列表的大小设置为 size。 如果 size 大于当前大小,则将元素添加到末尾;新元素使用默认构造值进行初始化。 如果 size 小于当前大小,则从末尾删除元素。
resize() 不再缩小容量。要摆脱多余的容量,请使用squeeze()。
36、void shrink_to_fit() / void squeeze()
释放任何不需要存储项目的内存。通常很少需要调用此函数。
37、QList<T> sliced(qsizetype pos, qsizetype n)
QList<T> sliced(qsizetype pos)
返回包含此列表的 n 个元素的子列表,从位置 pos 开始。
38、void swapItemsAt(qsizetype i, qsizetype j) 【实用】
将索引位置 i 的项目与索引位置 j 的项目交换。
39、T takeAt(qsizetype i)
移除索引位置 i 处的元素并返回它。
等同于:
T t = at(i);
remove(i);
return t;
40、QList::value_type takeFirst() / QList::value_type takeLast()
删除列表中的第一项 / 最后一项并返回它。
41、T value(qsizetype i)
返回列表中索引位置 i 处的值。
如果索引 i 超出范围,则该函数返回一个默认构造的值。
如果确定 i 在范围内,可以使用 at() 代替,它返回常引用,稍微快一点。
T value(qsizetype i, QList::parameter_type defaultValue)
如果索引 i 超出范围,则函数返回 defaultValue。
三、相关非成员
1、template <typename T, typename AT> qsizetype erase(QList<T> &list, const AT &t)
从列表列表中删除所有与 t 比较相等的元素。 返回删除的元素数。
注意:与 QList::removeAll() 不同,t 不允许是对列表内元素的引用。如果不能确定,应获取 t 的副本并使用副本调用此函数。
2、template <typename T, typename Predicate> qsizetype erase_if(QList<T> &list, Predicate pred)
用法和 removeIf() 相似。
更多推荐
所有评论(0)