为什么我无法在自定义类的复制构造函数中移动此向量?

时间:2017-12-22 18:39:29

标签: c++ c++11 move-semantics move-constructor

class TestClass 
{
  public:
  TestClass(){
      cout<<"constructor"<<endl;
      p = {1,2,3};
      cout<<(unsigned int *)(this->p.data())<<endl;
  }
  TestClass(const TestClass& test):  p(std::move(test.p))
  {
      cout <<"copy constructor"<<endl;
      cout<<(unsigned int *)(this->p.data())<<endl;

  }
  TestClass(TestClass && test): p(std::move(test.p))
  {
      cout <<"move constructor"<<endl;
      cout<<(unsigned int *)(this->p.data())<<endl;
  }
  private:
      std::vector<int> p;
};


int main()
{
  TestClass t{};
  TestClass p{t};
  TestClass s{std::move(p)};
  return 0;
}

输出

 constructor
 0xb92bf0
 copy constructor
 0xb915b0
 move constructor
 0xb915b0

我只是想知道为什么下面的构造函数的地址与下面的复制构造函数不同。根据我的理解,即使它是一个复制构造函数,但我使用std :: move来获取一个右值引用,并且应该调用向量的移动构造函数,因此它们应该是同一个对象。

1 个答案:

答案 0 :(得分:4)

std::move只是将传递给它的任何内容转换为xvalue,因此rvalue-references可以绑定到它并可能窃取其资源。这里:

TestClass(const TestClass& test):  p(std::move(test.p))

std::move将生成const std::vector<int> &&类型的表达式,如您所见,它具有const限定符。如果在[vector]上检查std::vector的复制和移动构造函数,您将看到move-constructor需要类型std::vector<T> &&的表达式和复制构造函数期待const std::vector<T> &

vector(const vector& x);
vector(vector&&) noexcept;

std::move(test.p)的结果与这两个构造函数进行比较。因为rvalue-reference不会绑定到具有const限定符的类型(除非rvalue-reference是const - 限定的),所以move-constructor重载并不是一个好的候选者。另一个候选者(复制构造函数)确实接受const - 限定类型,因为xvalues具有与rvalues相同的属性:

  

http://en.cppreference.com/w/cpp/language/value_category#rvalue

     

rvalue可用于初始化const左值引用,在这种情况下,rvalue标识的对象的生命周期将延长,直到引用范围结束。

,复制构造函数是一个很好的候选者并被选中。