我正在尝试编写一种有效的方法来将图像(QImage - Qt5.3)分配给我的类的成员变量:
void ImageView::setImage(QImage&& image){
std::cout << &image << std::endl;
_image = image;
//_image = std::move(image);
std::cout << &_image << std::endl;
_imageAssigned = true;
updateResizedImage();
update();
}
我可能会使用两行代码,第一行是 _image = image;
,第二行是 _image = std::move(image);
。现在我认为第一行应该完全没问题,实际上应该使用 QImage 的 =operator 重载,它采用右值引用,因为 image 已经是右值引用。然而,Visual Studio 的工具提示显示使用了普通的 = 运算符。如果我改用第二行,工具提示会显示使用右值的重载。现在我的问题是为什么会这样。第一行还不够吗?对已经是右值引用的变量调用 move 对我来说似乎是多余的。
我尝试通过输出指针来自己测试(如代码中所示)。现在,无论我使用哪一行,指针都是不同的。这让我感到困惑。看起来,我的代码没有按照我想的那样运行。谁能告诉我我做错了什么?
谢谢你的帮助
最佳答案
具有名称的对象是左值。声明为QImage&&
指示只能将右值绑定(bind)到此引用,但引用本身始终是左值:它有一个名称。如果你想转发一个实体的右值,你必须使用 std::move()
明确地这样做。 .如果推导了右值(即,您使用 T&&
形式的推导模板参数,其中 T
是模板参数),您将使用 std::forward<T>(arg)
有条件地转发右值。 .
image
的地址和 _image
当然,它们是不同的,因为它们首先是不同的对象。如果QImage
包含一个带有地址的对象,您可以验证该对象是否已使用该地址移动。例如,如果您使用 std::vector<T>
而不是 QImage
您可以使用类似这样的方法来确定数组是否已移动:
void f(std::vector<T>&& v) {
std::cout << (v.empty()? 0: v.data()) << '\n';
std::vector<T> other;
other = v; // will be copied
std::cout << (other.empty()? 0: v.data()) << '\n';
other = std::move(v); // will be moved
std::cout << (other.empty()? 0: v.data()) << '\n';
}
关于c++ - 将右值引用分配给成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27593839/