为什么我不能从 move copy ctor 调用 move assignment?
Why can't I call move assigment from move copy ctor?
如果我可以从 move ctor 调用 move assignment op,有时看起来可以节省时间。但是当我尝试时,它会直接将我带到常规作业:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { }
MyClass(const MyClass& other) { /* do some stuff */ }
MyClass(MyClass&& other); //move ctor
const MyClass& operator= (const MyClass& other);
const MyClass& operator= (MyClass&& other); //move =
};
MyClass::MyClass(MyClass&& other) //move ctor
{
cout << "Calling move ctor\n";
*this = other; //<<--THIS IS THE PROBLEM
}
const MyClass& MyClass::operator= (MyClass&& other) //move =
{
cout << "Calling move =\n";
return *this;
}
const MyClass& MyClass::operator= (const MyClass& other)
{
cout << "Calling standard =\n";
if (this == &other) return *this;
return *this;
}
MyClass makeVectorToTestMoveCtor() { MyClass V; return V; }
int main ()
{
MyClass V = makeVectorToTestMoveCtor();
return 0;
}
我可以用std::move强制它:
cout << "Calling move ctor\n";
*this = std::move(other);
...但如果这不是一个坏主意,我当然不需要强迫它吧?我应该在这里做什么?
这是个坏主意 - 赋值的语义是关于改变现有对象的状态以使其与另一个对象匹配。存在构造函数来初始化以前不存在的对象。
此外,您不能使用成员初始化列表来初始化成员,这需要您的数据成员是default-constructible和非const
。
如果有的话,根据构造函数定义赋值会更有意义,例如:
foo& foo::operator=(foo&& rhs)
{
this->~foo();
new (this) foo{std::move(rhs};
}
对于上面的代码片段,您需要注意不要触发 UB,但是:
一般来说,除非您可以让编译器为您生成它们,否则我会分别定义这两个运算符。
构造是更基础的操作。您必须先有一个构造的对象,然后才能对其进行分配。根据构造而不是相反的方式写作业。
如果我可以从 move ctor 调用 move assignment op,有时看起来可以节省时间。但是当我尝试时,它会直接将我带到常规作业:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { }
MyClass(const MyClass& other) { /* do some stuff */ }
MyClass(MyClass&& other); //move ctor
const MyClass& operator= (const MyClass& other);
const MyClass& operator= (MyClass&& other); //move =
};
MyClass::MyClass(MyClass&& other) //move ctor
{
cout << "Calling move ctor\n";
*this = other; //<<--THIS IS THE PROBLEM
}
const MyClass& MyClass::operator= (MyClass&& other) //move =
{
cout << "Calling move =\n";
return *this;
}
const MyClass& MyClass::operator= (const MyClass& other)
{
cout << "Calling standard =\n";
if (this == &other) return *this;
return *this;
}
MyClass makeVectorToTestMoveCtor() { MyClass V; return V; }
int main ()
{
MyClass V = makeVectorToTestMoveCtor();
return 0;
}
我可以用std::move强制它:
cout << "Calling move ctor\n";
*this = std::move(other);
...但如果这不是一个坏主意,我当然不需要强迫它吧?我应该在这里做什么?
这是个坏主意 - 赋值的语义是关于改变现有对象的状态以使其与另一个对象匹配。存在构造函数来初始化以前不存在的对象。
此外,您不能使用成员初始化列表来初始化成员,这需要您的数据成员是default-constructible和非const
。
如果有的话,根据构造函数定义赋值会更有意义,例如:
foo& foo::operator=(foo&& rhs)
{
this->~foo();
new (this) foo{std::move(rhs};
}
对于上面的代码片段,您需要注意不要触发 UB,但是:
一般来说,除非您可以让编译器为您生成它们,否则我会分别定义这两个运算符。
构造是更基础的操作。您必须先有一个构造的对象,然后才能对其进行分配。根据构造而不是相反的方式写作业。