为什么不能从移动拷贝ctor调用移动分配?

时间:2019-06-27 20:20:36

标签: c++17 move-semantics

如果我可以从移动ctor调用移动分配操作,有时看起来很节省时间。但是,当我尝试时,我将直接进入常规作业:

#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); 

...但是,如果这不是一个坏主意,那么我当然不需要强制执行吗?我应该在这里做什么?

2 个答案:

答案 0 :(得分:0)

这是一个坏主意-赋值的语义是关于使现有对象的状态发生变化以使其与另一个对象匹配。存在构造函数以初始化以前不存在的对象。

此外,您不能使用成员初始化列表初始化成员,这要求您的数据成员必须是默认可构造的并且不能为const

如果有的话,用构造函数来定义分配会更有意义,例如:

foo& foo::operator=(foo&& rhs)
{
    this->~foo();
    new (this) foo{std::move(rhs};
}

对于以上代码段,您需要注意不要触发UB,不过:Placement new and assignment of class with const member


通常,除非您让编译器为您生成它们,否则我只会分别定义两个运算符。

答案 1 :(得分:0)

建筑是最基本的操作。您必须先拥有一个构造对象,然后才能对其进行分配。按照构造而不是相反的方式写作业。