在移动赋值运算符中,我应该使用std :: move还是std :: swap?
我做了:
void Swap(Image& Img) {/*Swap everything here*/}
Image& Image::operator = (const Image &Img)
{
if (this != &Img) Img.Swap(*this); //Compiler error for copy assignment.. no match for swap taking const..
return *this;
}
Image& Image::operator = (Image&& Img)
{
Img.Swap(*this);
return *this;
}
假设我和I有两个图像:
I = std::move(J);
发生的事情是来自I和J的数据被交换,所以现在J具有I的像素,反之亦然。这是正常的吗?我认为移动任务应该被盗并摧毁?这样当J移动到I时,我得到J和J的内容被破坏了?但是我在网上看到了这些例子
我可以在移动构造函数中看到相同的代码,但是如何在赋值中工作?它似乎没有意义:S
std :: move是否也应该用于移动构造函数?如果我在构造函数中使用std :: move,它会崩溃我的程序:
Image::Image(Image&& Img) : Pixels(), Info(), /*Default everything*/
{
this->Swap(Img);
Img.Pixels.clear();
}
上面的构造函数工作..但是,如果我在构造函数中使用std :: move:
Image::Image(Image&& Img) : Pixels(std::move(Img.Pixels)), Info(std::move(Img.Info)), /*move everything*/
{
//Do I need to set Img's values to default? Or does std::move do that?
}
当尝试使用移动的对象时,这将导致我的程序崩溃:
Image I = Image("C:/Image.bmp");
Image J = std::move(I);
I.Draw(...); //Crashes program if using std::move. If using the swap version of the constructor, it works. I assume it's because swap version defaults everything.
答案 0 :(得分:3)
如果您支持有效的交换并移动构造,那么您应该只有一个赋值运算符,按值:
Foo & operator=(Foo rhs) { rhs.swap(*this); }
如果用户传递了const-reference,那么无论如何都需要进行复制。如果用户传递了一个rvalue,那么构造局部变量rhs
很便宜。
换句话说,在三个中:复制/移动构造函数,复制/移动赋值和交换,你只需要深入实现两个(其中一个应该是构造函数)。