【发布时间】:2017-01-17 17:14:28
【问题描述】:
我正在学习的 C++ 课程中的移动构造函数实现示例如下所示:
/// 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 是 std::array<Wheel, 2> 类型的成员,Wheel 只包含 double m_speed 和 bool m_rotating。在 Motorcycle 类中,@ 987654327@ 和m_direction 也是doubles。)
我不太明白为什么需要清除ori 的值。
如果Motorcycle 有任何我们想要“窃取”的指针成员,那么当然,我们必须设置ori.m_thingy = nullptr 以免,例如delete m_thingy 两次。但是,当字段包含对象本身时,这有关系吗?
我问了一位朋友,他们将我指向this page,上面说:
Move 构造函数通常“窃取”参数持有的资源(例如,指向动态分配对象的指针、文件描述符、TCP 套接字、I/O 流、正在运行的线程等),而不是复制它们并离开某些有效但不确定的状态的参数。例如,从
std::string或std::vector移动可能会导致参数为空。但是,不应依赖此行为。
谁定义了不确定状态的含义?我看不出将速度设置为 0.0 比保持不变更不确定。就像引用中的最后一句话所说的那样——代码不应该依赖于从 Motorcycle 移出的状态,所以为什么还要清理它呢?
【问题讨论】:
-
我看不出构造函数主体中的三行有什么特别的原因。我也看不出有什么特别的理由为这个类设置一个移动构造函数——它看起来和复制构造函数做的事情完全一样。
-
@Lynn:无论如何,在构造函数中执行 IO 是不好的巫术,恕我直言
-
@PatrickCollins 我同意。我不太喜欢这门课。 :(
-
@IgorTandetnik 它做的事情并不完全相同;它移动了
wheels数组。 -
@immibis 确实如此。然而,
Wheel类的口头描述表明移动这个数组与复制它没有区别。
标签: c++ c++11 move-constructor