QT为了提升性能,好多容器类采用了写时复制,类似多引用共享一份数据,有必要的时候再拷贝。
通过代码实际验证来说明
#include <qdebug.h>
#include <QtCore/QCoreApplication>
#include <qvector.h>
QVector<int> createVector() {
QVector<int> vec{ 1, 2, 3 };
int* ptr0 = vec.data();
*ptr0 = 20;
qDebug() << *ptr0;
return vec;
}
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QVector<int> vecA = createVector();
int* ptrA = vecA.data();
qDebug() << *ptrA;
QVector<int> vecB = vecA;
int* ptrB0 = vecB.data();
qDebug() << *ptrB0;
vecB[0] = 10;
int* ptrB1 = vecB.data();
qDebug() << *ptrB1;
return a.exec();
}
1. 函数返回值为容器类时,实际上是浅拷贝,验证结果如下:
- 子函数内数据的地址与返回值地址是相同的,类似“移动语义”

2. QVector vecB = vecA; // 浅拷贝,共享数据

3. int* ptrB0 = vecB.data(); // 触发了拷贝

关于Qvector浅拷贝的常用操作
使用 mid()、left() 或 right() 截取子数组
- QVector 的 mid()、left()、right() 方法默认会创建一个新的 QVector 实例,但底层数据会通过隐式共享机制与原数组共享同一内存块,直到修改时才触发深拷贝。
QVector<int> original = {1, 2, 3, 4, 5};
QVector<int> subVector = original.mid(1, 3);
subVector[0] = 99;
存储指针或轻量对象
- 若元素本身需要避免深拷贝(如对象含指针成员),可将 QVector 存储为指针或轻量句柄,直接共享指针而非对象数据。
QVector<MyClass*> ptrVector;
ptrVector.append(new MyClass(1));
ptrVector.append(new MyClass(2));
QVector<MyClass*> subPtrVector = ptrVector.mid(0, 2);
使用 QVector::fromRawData(谨慎使用)
- 对于简单数据类型(如 int、double),可通过 QVector::fromRawData 直接引用原数组内存,实现零拷贝。但需注意:
- 数据必须连续:原数组需为连续内存。
- 只读操作:生成的 QVector 默认只读,若需修改需先调用 detach()(触发深拷贝)。
int rawData[] = {1, 2, 3, 4, 5};
QVector<int> rawVector = QVector<int>::fromRawData(rawData, 5);
if (!rawVector.isDetached()) {
rawVector.detach();
}
rawVector[0] = 99;