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来获取一个右值引用,并且应该调用向量的移动构造函数,因此它们应该是同一个对象。
答案 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标识的对象的生命周期将延长,直到引用范围结束。
,复制构造函数是一个很好的候选者并被选中。