【发布时间】:2020-01-15 19:10:35
【问题描述】:
我有一个将值插入 QVector 的小型测试程序。 QVector 在开始时被保留以分配最少的内存量。我验证容量是正确的,并且 QVector 的大小没有超过容量。
我观察到将数据附加到 QVector 不会更改第一个元素的地址。 到目前为止一切顺利。
然后我使用 QSplineSeries 类的 replace() 方法将数据从向量复制到图表。调用此方法后,我再次检查 QVector 中第一个元素的地址,令我惊讶的是地址已更改!
每次调用此方法时都会发生这种情况,我想了解为什么会发生这种情况。我怀疑可能与 Qt 的容器的隐式共享有关,但我不明白为什么这应该改变这个容器的地址。
示例代码和输出如下所示。
#include <QApplication>
#include <QDebug>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
#include <QtCharts/QSplineSeries>
#include <memory>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
auto chart = std::make_unique<QtCharts::QChartView>(new QtCharts::QChart());
chart->chart()->addSeries(new QtCharts::QSplineSeries);
QVector<QPointF> vector;
vector.reserve(1000);
while (true) {
vector.append(QPointF(0, 0));
qDebug() << "1. Size: " << vector.size() << " Capacity: " << vector.capacity();
qDebug() << "1. Address of first element: " << &vector[0];
auto series = dynamic_cast<QtCharts::QSplineSeries*>(chart->chart()->series().at(0));
series->replace(vector);
qDebug() << "2. Size: " << vector.size() << " Capacity: " << vector.capacity();
qDebug() << "2. Address of first element: " << &vector[0];
}
return a.exec();
}
输出
- 尺寸:1 容量:1000
- 第一个元素的地址:0x222725d61e8
- 尺寸:1 容量:1000
- 第一个元素的地址:0x222725dc0d8
- 大小:2 容量:1000
- 第一个元素的地址:0x222725dc0d8
- 大小:2 容量:1000
- 第一个元素的地址:0x222725d61e8
- 大小:3 容量:1000
- 第一个元素的地址:0x222725d61e8
- 大小:3 容量:1000
- 第一个元素的地址:0x222725dc0d8
- 大小:4 容量:1000
- 第一个元素的地址:0x222725dc0d8
- 大小:4 容量:1000
- 第一个元素的地址:0x222725d61e8
- 大小:5 容量:1000
- 第一个元素的地址:0x222725d61e8
- 大小:5 容量:1000
- 第一个元素的地址:0x222725dc0d8
Link to the source code of the QSplineSeries::replace(QVector) call here
编辑
我刚刚意识到 QVector 的赋值运算符在 QSplineSeries::replace 中被调用,看起来像 this。这意味着 QSplineSeries 中的内部向量复制了我传入的 QVector,但我仍然不明白为什么我传入的 QVector 会更改它的地址。
【问题讨论】: