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

问题描述 投票:3回答:1
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来获取一个右值引用,并且应该调用vector的move构造函数,因此它们应该是同一个对象。

c++ c++11 move-semantics move-constructor
1个回答
4
投票

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

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

std::move将生成const std::vector<int> &&类型的表达式,如您所见,它具有const限定符。如果你在std::vector上检查[vector]的复制和移动构造函数,你会发现move-constructor需要一个类型为std::vector<T> &&的表达式,而copy-constructor需要一个const std::vector<T> &

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.