C ++ 11为具有对象作为成员的类移动赋值运算符 - 初级级别

时间:2014-09-30 22:08:10

标签: c++11 move

我对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;
}

我不明白为什么第一种方法不起作用。我在想,既然构造函数会调用它的成员构造函数,那么移动赋值运算符也应该这样做。我错了还是我在代码中犯了错误?有人可以解释一下,谢谢!

2 个答案:

答案 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;
}