[英]using std::move to prevent copying
I have the following code: 我有以下代码:
#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;
}
With output (VS2013, Release build) 带输出(VS2013,发布版本)
section I
A()
A()
B(const A&)
a.x.size=10
section II
A()
A()
B(const A&&)
~A()
b.x.size=10
section III
~B()
~A()
~B()
~A()
~A()
Why axsize() within "section I" has size 10? 为什么“ I部分”中的axsize()的大小为10? I thought that std::move should move all data from ax to yx 我认为std :: move应该将所有数据从ax移到yx
Why did "section II" call constructor A() twice? 为什么“第二节”两次调用构造函数A()? I thought that B(const A&&) would prevent excessive copying of A 我认为B(const A &&)可以防止A的过度复制
UPDATE UPDATE
see fixed code at http://pastebin.com/70Nmt9sT 请参阅http://pastebin.com/70Nmt9sT上的固定代码
T&&
and const T&&
are not the same type. T&&
和const T&&
不是同一类型。 You almost never want a const
rvalue reference - you can't steal its resources since you made it const
! 您几乎永远不需要const
rvalue引用-自从将其const
后就无法窃取其资源! x = std::move(ax);
in B(const A&a)
copies ax
since the return type of std::move(ax)
is const vector<int>&&
. B(const A&a)
const vector<int>&&
复制ax
因为std::move(ax)
的返回类型是const vector<int>&&
。 B(const A&&)
calls the default constructor of A
since it is derived from A
, and the member initializer list does not make an attempt to construct the base A
. 构造函数, B(const A&&)
调用的默认构造A
因为它是衍生自A
,和成员初始化列表不会使试图构造基A
。 This is the second A
call. 这是第二个A
呼叫。 Why
axsize()
within "section I" has size 10? 为什么“ I部分”中的axsize()
大小为10? I thought thatstd::move
should move all data fromax
toyx
我认为std::move
应该将所有数据从ax
移到yx
This is because of B(const A&& a)
. 这是因为B(const A&& a)
。 Since a
is const
within that constructor, you only have const
access to its member x
, and calling std::move
on a vector<T> const
results in a vector<T> const&&
which cannot bind to vector
's move constructor (which takes a vector<T>&&
argument). 由于a
是该构造const
,因此您只能对其成员x
进行const
访问,并且在vector<T> const
上调用std::move
导致vector<T> const&&
不能绑定到vector
的move构造函数(采用vector<T>&&
参数)。 Instead it ends up calling the copy constructor, which leaves the source object unmodified. 相反,它最终调用了复制构造函数,这使源对象保持不变。
Why did "section II" call constructor
A()
twice? 为什么“第二节”两次调用构造函数A()
? I thought thatB(const A&&)
would prevent excessive copying ofA
我认为B(const A&&)
可以防止A
过度复制
The first default construction occurs within the body of ret_a()
. 第一个默认构造发生在ret_a()
的主体内。 The second default construction is that of the A
sub-object of B
. 第二种默认构造是B
的A
子对象的构造。 To avoid the second one move
the A
instance in the member initializer list. 为了避免第二步,在成员初始化器列表中move
A
实例。
B(const A&&a)
: A(std::move(a))
{
std::cout << "B(const A&&)" << std::endl;
y.resize(x.size());
}
Note that the move
doesn't actually result in moving the contents of a
due to the same reason as explained above. 需要注意的是, move
实际上并没有导致的内容移动a
因同样的原因如上所述。 Moreover, even modifying the signature to B(A&& a)
would not result in the contents of a
being moved because the user provided copy constructor and destructor definitions prevent implicit generation of a move constructor for A
, and it'll be copied instead. 此外,即使修改签名B(A&& a)
不会导致内容a
移动由于用户提供拷贝构造函数和析构函数的定义,防止转移构造的隐代A
,它会被复制而不是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.