![](/img/trans.png)
[英]C++ Move constructor for object with std::vector and std::array members
[英]c++ copy constructor vs move constructor for std::vector
我有一个类,它包含一个std::vector
struct Mystruct
{
Mystruct(const std::vector<int>& w): v(w)
{
std::cout << "Copy constructor :" << v.at(0) << "\n";
}
Mystruct(const std::vector<int>&& w): v(w)
{
std::cout << "Move Constructor :" << v.at(0) << "\n";
}
private:
std::vector<int> v;
};
我创建像这样的对象
int main()
{
auto x = std::vector<int> {1,2,3};
Mystruct M1(x);
Mystruct M2(std::vector<int> {3,2,1});
return 0;
}
M1
使用拷贝构造函数和构造M2
使用“移动”的构造,但是在gdb同时运行assignements保持了V和W的不同的地址,同样的情况,如果我在初始化列表中使用V(标准::移动(W))第二个构造函数。 所以我猜两个人都在复制w的内容,这是正确的吗? 如果是这种情况,我怎样才能移动w的内容而不是复制它们
首先,移动对象不会改变其地址。 根据定义,您不能更改对象的地址,因为地址是对象定义的一部分。 如果您有不同的地址,则会有不同的对象。 什么移动(至少在标准库中的类)是移动对象的动态分配资源的所有权。
其次,你没有动任何东西。 为了移动东西,你必须调用移动构造函数。 这意味着你需要传递一个r值。 命名对象永远不是r值。 所以即使你有一个r值引用,你仍然需要使用std::move
来转换它。 但在你的情况下,即使这还不够。 在标准库中,所有移动构造函数都具有Type(Type&&)
签名,而不是Type(const Type&&)
。 如果传递一个const值,即使使用std::move
它,它也会调用复制构造函数,而不是移动构造函数。 为了调用移动构造函数,您的对象不能是const。
因此,移动矢量*的构造函数应如下所示:
Mystruct(std::vector<int>&& w): v(std::move(w))
{
std::cout << "Move Constructor :" << v.at(0) << "\n";
}
并且为了比较地址以查看它是否实际被移动,你不应该比较v
和w
的地址(那些不会,也不能改变),而是v.data()
和w.data()
,这一点动态分配的向量资源。
*不是移动构造函数。 移动构造函数将具有签名Mystruct(Mystruct&&)
或Mystruct(const Mystruct&&)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.