(为什么)应该移动构造函数或移动赋值运算符清除其参数? [英] (Why) should a move constructor or move assignment operator clear its argument?
问题描述
/// 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 double
s.)
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 astd::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屋!