C++:传递指向函数中类的指针会导致数据复制?
C++: passing a pointer to a class in a function results in data copy?
在我的Qt5应用程序中,我有一个类'Image',其中包含一个带有像素值的一维向量,以及一个减去参考图像的成员函数,如下所示:
class Image {
public:
QVector<float> pixels;
void subtract(Image *refImage) {
long i = 0;
for (auto &pix : pixels) {
pix -= refImage->pixels[i];
++i;
}
}
}
我还有一个类"数据",包含一个指向参考图像的指针:
class Data {
public:
Image* refImage;
}
最后,在我的主函数中,我像这样从图像中减去参考图像:
int main() {
...
Image *image = new Image(args);
Data *referenceData = new Data(args);
image->subtract(referenceData->refImage);
...
}
由于我正在传递一个指向减法((的指针,因此我不希望制作refImage的副本。但是,我观察到的是,对于每次调用减去((,我的应用程序的内存占用量都会增加大约"refImage"的大小。我不明白这一点。我认为通过将指向函数的类的指针传递给函数,我可以避免复制?
您可能遇到过Qt容器与标准库容器的不同之处之一。具体来说,Qt使用隐式共享和写入时复制。这意味着,当创建容器的副本时,副本和原始副本都指向相同的数据。只有当尝试更改其中一个容器的内容时,才会进行深层复制。(虽然修剪后的示例没有显示正在制作的副本,但很可能复制正在实际代码中的某个地方进行。
让我们将其应用于您的示例。当您访问参考图像的数据时,您有一个非const
QVector
,并且您通过operator[]
访问数据。这将返回对向量元素的非常量引用。这意味着您可以写入它。你是否真的写信给它并不重要。该对象无法知道您将如何处理引用,因此它必须为潜在的写入做好准备。由于数据(大概(是共享的,因此会触发深层复制。refImage->pixels
中的数据被复制到一个新的内存块中,您可以覆盖该内存块,而不会影响那里的任何副本。因此,会消耗更多内存。
如果要在不触发深层复制的情况下完成任务,请将refImage->pixels[i]
更改为refImage->pixels.at(i)
或refImage->pixels.value(i)
,因为您不检查参考矢量的大小。或者,声明要Image const *
refImage
,以便使用const QVector
使用的operator[]
版本;此版本返回常量引用,该引用不会触发深层复制。
改编自我对类似问题的回答。
- 检查输入 std::array 指针数据是否等于某个常量数组
- 指针数据类型变量如何包含对象?
- 如何在C++中使用类对象访问指针数据成员
- 如何强制实施有关指针数据成员的常量正确性
- 为什么指针>数据有效,而 *double_pointer->data 不起作用?
- 如何从C++中的原始指针数据构造张量流::张量
- 检查课程是否具有指针数据成员
- 处理类的指针数据成员的动态内存
- 在堆上启动的指针数据成员
- 具有指针数据类型的非类型函数模板参数
- 如何将复杂的指针数据作为属性放入qt-plugin-xml文件中
- C++指向函数作为参数的指针.数据类型不兼容
- 初始化指针数据结构的空间复杂性
- 运算符重载与 C++ : 具有指针数据成员的类
- 我是否需要清理非指针数据成员
- 在堆或堆栈上的指针类实例中分配C++非指针数据成员
- 函数结束后丢失指针数据
- C++ 如何确保复制构造函数不会修改原始对象的指针数据成员?
- 为什么从派生类访问基类的数据时会返回无意义的数据(我认为是指针数据)
- 将原始鼠标/指针数据转换为有意义的内容