C++对象没有得到std::moved吗?
Does the C++ Object not get std::moved?
我得到了以下代码:(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;
};
int main ()
{
auto factory = std::make_unique < Factory > ();
Worker w1 ("Bob");
factory->addWorker (w1);
Worker & workerRef = factory->getLastWorker ();
//workerRef.changeName("Mary");
return 0;
}
我有一个 Factory
存储在它的 Workers
向量中。当我 运行 main()
我得到以下输出:
Factory got created!
Bob got moved!
Bob got destroyed!
Factory got destroyed!
Bob got destroyed!
但我不明白为什么 Bob got destroyed!
出现两次,因为我认为 Worker w1
被移动到 Factory
中的矢量 workers
。此外,如果您在 workerRef.changeName("Mary");
中发表评论,代码会因 Segmentation fault
.
而崩溃
我用 c++ 编码已经一个月了,在这里真的很挣扎。我已经用谷歌搜索了一段时间,但找不到提示,所以任何帮助都很棒!
很简单:
也调用了一个空的对象析构函数。
在move constractor
中,旧对象将其内容(尤其是指针)传输给新对象,并变为空对象,然后在作用域结束时作为空对象销毁。
请注意,在移动构造函数之后,原始构造函数不应再调用 Bob...
移动只是移动对象的内容(如果这样实现,它可以只是复制)。这并不意味着原始对象消失了,只是它的值可能会发生变化。
您的示例在两个地方创建两个 对象:
Worker w1 ("Bob");
this->workers.push_back (std::move (worker));
第二个偷了第一个的胆量(无论如何,从表面上看),但第一个还活着。任何有生命的对象都会在其生命周期结束时调用其析构函数(对于 w1
这是 main
的结束)。
首先,你的移动构造函数并没有真正移动任何东西,它只是复制字符串。
当您将 Worker
推回到向量中时,您仍然有两个 Worker
对象:一个在 main
函数中,一个在向量中。这两个对象都需要销毁。
您仍然有两个对象,一个在 main
中,一个在向量中。
"Moving" 实际上并没有移动一个对象,只是它的内容——至少在概念上是这样(std::move
只是一个类型转换)。
不一定是任何东西都在移动的情况,就像在你的情况下, "move constructor" 的行为完全像一个复制构造函数。
如果你想要更多的"move-y"移动构造函数,你应该写:_name (std::move(other._name))
,这将使w1
的名字为空。
崩溃的原因是你忘了在getLastWorker
中写return
。
提高编译器的警告级别并注意它。
我得到了以下代码:(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;
};
int main ()
{
auto factory = std::make_unique < Factory > ();
Worker w1 ("Bob");
factory->addWorker (w1);
Worker & workerRef = factory->getLastWorker ();
//workerRef.changeName("Mary");
return 0;
}
我有一个 Factory
存储在它的 Workers
向量中。当我 运行 main()
我得到以下输出:
Factory got created!
Bob got moved!
Bob got destroyed!
Factory got destroyed!
Bob got destroyed!
但我不明白为什么 Bob got destroyed!
出现两次,因为我认为 Worker w1
被移动到 Factory
中的矢量 workers
。此外,如果您在 workerRef.changeName("Mary");
中发表评论,代码会因 Segmentation fault
.
我用 c++ 编码已经一个月了,在这里真的很挣扎。我已经用谷歌搜索了一段时间,但找不到提示,所以任何帮助都很棒!
很简单:
也调用了一个空的对象析构函数。
在move constractor
中,旧对象将其内容(尤其是指针)传输给新对象,并变为空对象,然后在作用域结束时作为空对象销毁。
请注意,在移动构造函数之后,原始构造函数不应再调用 Bob...
移动只是移动对象的内容(如果这样实现,它可以只是复制)。这并不意味着原始对象消失了,只是它的值可能会发生变化。
您的示例在两个地方创建两个 对象:
Worker w1 ("Bob");
this->workers.push_back (std::move (worker));
第二个偷了第一个的胆量(无论如何,从表面上看),但第一个还活着。任何有生命的对象都会在其生命周期结束时调用其析构函数(对于 w1
这是 main
的结束)。
首先,你的移动构造函数并没有真正移动任何东西,它只是复制字符串。
当您将 Worker
推回到向量中时,您仍然有两个 Worker
对象:一个在 main
函数中,一个在向量中。这两个对象都需要销毁。
您仍然有两个对象,一个在 main
中,一个在向量中。
"Moving" 实际上并没有移动一个对象,只是它的内容——至少在概念上是这样(std::move
只是一个类型转换)。
不一定是任何东西都在移动的情况,就像在你的情况下, "move constructor" 的行为完全像一个复制构造函数。
如果你想要更多的"move-y"移动构造函数,你应该写:_name (std::move(other._name))
,这将使w1
的名字为空。
崩溃的原因是你忘了在getLastWorker
中写return
。
提高编译器的警告级别并注意它。