我对c ++ 11中的移动分配有一个初学者的问题。假设我有一个带有移动分配运算符的A类:
class A
{
public:
A();
~A();
A& operator=(A&&);
...
}
我还有一个包含A类对象的B类,并提供了一个移动赋值运算符
class B
{
public:
B();
~B();
B& operator=(B&&);
...
private:
A Test;
}
我在想的是B移动赋值运算符将调用其成员的移动赋值运算符,所以我尝试了这种方法:
B& B::operator=(B&& Other)
{
...
Test = Other.Test;
...
return *this;
}
但这不起作用,因为没有调用A类的移动分配。
相反,我能够通过使用此方法使程序正常工作:
B& B::operator=(B&& Other)
{
...
Test = std::move(Other.Test);
...
return *this;
}
我不明白为什么第一种方法不起作用。我在想,既然构造函数会调用它的成员构造函数,那么移动赋值运算符也应该这样做。我错了还是我在代码中犯了错误?有人可以解释一下,谢谢!
答案 0 :(得分:2)
Other.Test
不是右值表达式,因为它有一个名称。 OTOH std::move(Other.Test)
具有类型A
和值类别xvalue(即,右值)。因此,它可以绑定到移动构造函数。
(编辑:无耻地复制@ dyp的评论。谢谢,@ dyp和@KerrekSB。)
答案 1 :(得分:1)
@Pradhan是正确的 - 您需要使用std::move
来移动移动赋值运算符的实现中的成员。但是,如果只需要实现移动构造函数,那么您可以声明运算符使用默认实现:
#include <memory>
class A {
public:
A() : p{} { }
~A() { }
A &operator=(A &&) = default;
// Instead of:
// A &operator=(A &&other) {
// p = std::move(other.p);
// return *this;
// }
private:
std::unique_ptr<int> p;
};
int main() {
A a;
A b;
b = std::move(a);
return 0;
}