C++对象不能被std :: move?

Dum*_*ior 4 c++ move c++14

我得到以下代码:( Code Live:C++ Shell)

class Worker
{
public:
  Worker (std::string name):_name (name) {};

  Worker (const Worker & worker):_name (worker._name)
  {  std::cout << _name << " got copied!" << std::endl; }

  Worker (Worker && other):_name (other._name)
  {  std::cout << _name << " got moved!" << std::endl;  }

  ~Worker ()
  {  std::cout << _name << " got destroyed!" << std::endl;  }

  void changeName(std::string name)
  {  this->_name = name;  }

private:
  std::string _name;
};

class Factory
{
public:
  Factory ()
  {  std::cout << "Factory got created!" << std::endl;  }

   ~Factory ()
  {  std::cout << "Factory got destroyed!" << std::endl;  }

  void addWorker (Worker & worker)
  {  this->workers.push_back (std::move (worker));  }

  Worker & getLastWorker ()
  {  this->workers.back ();  }

private:
  std::vector < Worker > workers;
};
Run Code Online (Sandbox Code Playgroud)
int main ()
{
  auto factory = std::make_unique < Factory > ();
  Worker w1 ("Bob");
  factory->addWorker (w1);
  Worker & workerRef = factory->getLastWorker ();
  //workerRef.changeName("Mary");

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在矢量中Factory存储它Workers的地方.当我运行时,main()我得到以下输出:

Factory got created!
Bob got moved!
Bob got destroyed!
Factory got destroyed!
Bob got destroyed!
Run Code Online (Sandbox Code Playgroud)

但我无法Bob got destroyed!理解为什么会出现两次,因为我认为它Worker w1会移动到矢量workersFactory.另外,如果您在workerRef.changeName("Mary");代码崩溃中发表评论Segmentation fault.

我现在用c ++编写了一个月的代码并且在这里真的很挣扎.我已经谷歌搜索了一段时间,但找不到提示,所以任何帮助都很棒!

Sto*_*ica 7

移动只移动对象的内容(如果像这样实现,它可以只复制).这并不意味着原始对象消失,只是它的值可能会改变.

您的示例在两个位置创建两个对象:

  1. Worker w1 ("Bob");
  2. this->workers.push_back (std::move (worker));

第二个从第一个(无论如何)偷走了胆量,但第一个仍然活着.任何生物都将在其生命周期结束时调用它的析构函数(因为w1它是关闭的main).

  • @GauravSehgal - 否.对象是存储区域,具有一定的价值.程序员可以更改值,但存储区域将保留为对象,直到调用析构函数.没有绕过它. (2认同)

mol*_*ilo 5

你仍然有两个对象,一个在main矢量中,一个在矢量内.

"移动"实际上并不移动对象,只移动其内容 - 至少在概念上(std::move仅仅是类型转换).
不一定是任何事情都会移动的情况,例如在你的情况下,"移动构造函数"的行为与复制构造函数完全相同.

如果你想要一个更"移动"的移动构造函数,你应该写 :_name (std::move(other._name)),这将使其w1名称为空.

究其原因,崩溃的是,你忘了写returngetLastWorker.
提高编译器的警告级别并注意它.