C++ 使用std::move防止复制
我有以下代码:C++ 使用std::move防止复制,c++,c++11,move-semantics,C++,C++11,Move Semantics,我有以下代码: #include <iostream> #include <vector> struct A { std::vector<int> x; A() { std::cout << "A()" << std::endl; } A(const A&) { std::cout << "A(const A&)" <
#include <iostream>
#include <vector>
struct A
{
std::vector<int> x;
A()
{
std::cout << "A()" << std::endl;
}
A(const A&)
{
std::cout << "A(const A&)" << std::endl;
}
~A()
{
std::cout << "~A()" << std::endl;
}
};
struct B : public A
{
std::vector<int> y;
B()
{
std::cout << "B()" << std::endl;
}
B(const A&a)
{
std::cout << "B(const A&)" << std::endl;
x = std::move(a.x);
y.resize(x.size());
}
B(const A&&a)
{
std::cout << "B(const A&&)" << std::endl;
x = std::move(a.x);
y.resize(x.size());
}
B(const B&)
{
std::cout << "B(const B&)" << std::endl;
}
~B()
{
std::cout << "~B()" << std::endl;
}
};
A ret_a()
{
A a;
a.x.resize(10);
return a;
}
int main()
{
std::cout << "section I" << std::endl << std::endl;
A a = ret_a();
B b(a);
std::cout << "a.x.size=" << a.x.size() << std::endl;
std::cout << std::endl << "section II" << std::endl << std::endl;
B b2(ret_a());
std::cout << "b.x.size=" << b.x.size() << std::endl;
std::cout << std::endl << "section III" << std::endl << std::endl;
return 0;
}
T&
和const T&
不是同一类型。您几乎从不需要const
rvalue引用-您无法窃取它的资源,因为您使它成为const
<代码>x=标准::移动(a.x)B(常数A&A)
中的code>复制A.x
,因为的返回类型是const vector&&
B(const A&&
调用A
的默认构造函数,因为它派生自A
,并且成员初始值设定项列表不会尝试构造基A
。这是第二个调用李>
为什么a.x.size()
在“第一节”中有10号尺寸?我认为std::move
应该将所有数据从a.x
移动到y.x
这是因为B(常数A和&A)
。由于a
在该构造函数中是const
,因此您只能const
访问其成员x
,并且对vector const
调用std::move
会导致vector const&&
无法绑定到vector
的move构造函数(它接受一个向量&&
参数)。相反,它最终调用复制构造函数,而不修改源对象
为什么“section II”调用构造函数A()
两次?我认为B(const A&&)
可以防止过度复制A
第一个默认构造出现在ret_a()
的主体中。第二个默认构造是B
的a
子对象的构造。为了避免第二个移动成员初始值设定项列表中的a
实例
B(const A&&a)
: A(std::move(a))
{
std::cout << "B(const A&&)" << std::endl;
y.resize(x.size());
}
B(常数A和&A)
:A(标准::移动(A))
{
标准::cout
B(const A&&a)
: A(std::move(a))
{
std::cout << "B(const A&&)" << std::endl;
y.resize(x.size());
}