【Qt】为什么QList是数组

为什么QList是数组

结论:在 Qt5 / Qt6 中,QList 不是链表,而是一个披着 list 名字的顺序容器。

一、QList 的历史背景
1. 名字的误导性

QList 这个名字,本身就极具欺骗性。

  • C++ 世界里:list ≈ 链表
  • Qt 世界里:QList ≠ 链表(至少现在不是)

很多认知混乱,并不是程序员不行,而是 API 命名留下的历史债务

2. Qt4 时代的 QList

在 Qt4 时代:

  • QList 对小对象做内嵌存储
  • 对大对象存指针
  • 行为介于数组和链表之间

当时它确实不像 QVector 那么"纯粹",也导致了大量口口相传的"经验结论"。

3. Qt5 / Qt6 的转折

为了性能和可预测性:

  • Qt5 起,QList 内部实现改为连续存储
  • 行为与 QVector 高度一致
  • 但 API 名字和接口被完整保留

于是诞生了今天这个局面:

实现已经变了,但大家的印象没更新。

二、QList 的真实本质
1. 内存模型

在 Qt5 / Qt6 中:

  • 元素存储在连续内存中
  • 支持随机访问 operator[]
  • 迭代器是 RandomAccessIterator

这三点中,只要成立一条,就已经可以否定"链表实现"。

2. 一个简单的自证方法

QList list;

list << 1 << 2 << 3 << 4;

for (int i = 0; i < list.size(); ++i)

{

​ qDebug() << &list[i];

}

如果它是链表,地址不可能连续。

三、QList 的核心特性
1. 随机访问

int v = list[i]; // O(1)

这是 QList 与真正链表在语义上的决定性分水岭

2. 隐式共享(Copy-On-Write)

QList a = b; // O(1)

a[0] = newValue; // 触发 detach

特点:

  • 拷贝"看起来"很便宜
  • 写入时才发生真实拷贝

这是 Qt 框架层面非常重要的设计哲学,但不是免费午餐

3. 插入 / 删除复杂度

list.insert(pos, value);

list.removeAt(pos);

  • 时间复杂度:O(n)
  • 会移动内存
  • 并不比 QVector 更擅长中间插入

因此:

用 QList 解决"频繁中间插入"的问题,是一个误判。

四、QList 的常见误用场景
1. 当成链表使用

QList<Node*> nodes;

// 期望中间插入很快

这是历史经验误导下最常见的错误。

2. 多线程下无锁读写

// 一个线程遍历

for (auto& v : list) {}

// 另一个线程 append

list.append(x);

隐式共享 不等于线程安全

这是 Qt 项目里非常隐蔽、但后果严重的坑。

五、QList vs QVector
1. 行为对比
  • 连续内存:两者都是
  • 随机访问:两者都是
  • 中间插入:两者都是 O(n)
2. 关键差异
  • QVector:语义清晰、无历史歧义
  • QList:API 兼容性强、历史包袱重
3. 工程选择原则

新代码默认 QVector,QList 只为兼容存在。

六、什么时候还可以接受 QList

不是绝对不能用,而是使用场景极少

  • 维护老 Qt 项目
  • 被动接收 Qt API 返回的 QList
  • 项目中已经大量使用 QList,且无性能/并发问题
七、结论
  1. QList 不是链表(Qt5 / Qt6)
  2. 不要用链表思维使用 QList
  3. 隐式共享在多线程下必须显式加锁
  4. QList 不适合并发队列
  5. 新代码优先 QVector
相关推荐
小小码农Come on几秒前
QT开发环境安装
开发语言·qt
云深处@3 分钟前
【C++】哈希表
开发语言·c++
weixin_452159556 分钟前
模板编译期条件分支
开发语言·c++·算法
guygg886 分钟前
傅立叶光学的Matlab实现方法
开发语言·matlab
码农六六9 分钟前
js函数柯里化
开发语言·前端·javascript
2501_9411481510 分钟前
C++ map / multimap 保姆级教程
java·开发语言·c++
ʚB҉L҉A҉C҉K҉.҉基҉德҉^҉大19 分钟前
C++中的策略模式进阶
开发语言·c++·算法
xb113225 分钟前
C#串口通信
开发语言·c#
小小码农Come on25 分钟前
QT内存管理
开发语言·qt
Zach_yuan32 分钟前
C++ Lambda 表达式从入门到进阶
开发语言·c++