繁体   English   中英

c ++ copy constructor vs std :: vector的move构造函数

[英]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";
}

并且为了比较地址以查看它是否实际被移动,你不应该比较vw的地址(那些不会,也不能改变),而是v.data()w.data() ,这一点动态分配的向量资源。

*不是移动构造函数。 移动构造函数将具有签名Mystruct(Mystruct&&)Mystruct(const Mystruct&&)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM