(为什么)应该移动构造函数或移动赋值运算符清除其参数? [英] (Why) should a move constructor or move assignment operator clear its argument?

查看:209
本文介绍了(为什么)应该移动构造函数或移动赋值运算符清除其参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  /// Move构造函数
Motorcycle :: Motorcycle(Motorcycle& ori)
:m_wheels(std :: move(ori.m_wheels)),
m_speed(ori.m_speed),
m_direction (ori.m_direction)
{
ori.m_wheels = array< Wheel,2>();
ori.m_speed = 0.0;
ori.m_direction = 0.0;
}

m_wheels std :: array< Wheel,2> Wheel 类型的成员只包含 double m_speed 摩托车类中, m_speed bool m_rotating code> m_direction 也是 double s。)



t很清楚为什么 ori 的值需要清除。



如果摩托车有任何指针成员,我们想窃取,然后肯定,我们必须设置 ori.m_thingy = nullptr 例如, delete m_thingy 两次。但是当字段包含对象本身时,这是否重要?



我问了一个朋友,他们指向我此页,其中包含:


移动构造函数通常 参数所拥有的资源(例如,指向动态分配的对象,文件描述符,TCP套接字,I / O流,运行线程等的指针),而不是复制它们,并将参数保留在某些有效但其他不确定状态。例如,从 std :: string 或从 std :: vector 移动可能会导致参数被留下空。


谁定义不确定状态是什么意思?我没有看到如何将速度设置为 0.0 是更多不确定,而不是离开它。就像报价中的最后一句话 - 代码不应该依赖于从摩托车移动的状态,所以为什么还要清理它?

解决方案

它们不需要清理。类的设计者决定将移动对象从零初始化是一个好主意。



请注意,一个情况是有意义的对象管理在析构函数中释放的资源。例如,指向动态分配的内存的指针。将指针保留在移动对象中未经修改意味着两个对象管理相同的资源。他们的破坏者都会尝试释放。


An example move constructor implementation from a C++ course I’m taking looks a bit like this:

/// Move constructor
Motorcycle::Motorcycle(Motorcycle&& ori)
    : m_wheels(std::move(ori.m_wheels)),
      m_speed(ori.m_speed),
      m_direction(ori.m_direction)
{
    ori.m_wheels = array<Wheel, 2>();
    ori.m_speed      = 0.0;
    ori.m_direction  = 0.0;
}

(m_wheels is a member of type std::array<Wheel, 2>, and Wheel only contains a double m_speed and a bool m_rotating. In the Motorcycle class, m_speed and m_direction are also doubles.)

I don’t quite understand why ori’s values need to be cleared.

If a Motorcycle had any pointer members we wanted to "steal", then sure, we’d have to set ori.m_thingy = nullptr so as to not, for example, delete m_thingy twice. But does it matter when the fields contain the objects themselves?

I asked a friend about this, and they pointed me towards this page, which says:

Move constructors typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, moving from a std::string or from a std::vector may result in the argument being left empty. However, this behaviour should not be relied upon.

Who defines what indeterminate state means? I don’t see how setting the speed to 0.0 is any more indeterminate than leaving it be. And like the final sentence in the quote says — code shouldn’t rely on the state of the moved-from Motorcycle anyway, so why bother cleaning it up?

解决方案

They don't need to be cleaned. The designer of the class decided it would be a good idea to leave the moved-from object zero initialized.

Note that a situation where is does make sense is for objects managing resources that get released in the destructor. For instance, a pointer to dynamically allocated memory. Leaving the pointer in the moved-from object unmodified would mean two objects managing the same resource. Both their destructors would attempt to release.

这篇关于(为什么)应该移动构造函数或移动赋值运算符清除其参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆