说 C++ 对象是可移动的到底是什么意思?

use*_*390 9 c++ language-lawyer move-semantics

鉴于以下定义:

  • 对象——保存某种类型值的连续内存区域。
  • value -- 根据对象类型解释的对象的位。

C++ 编程语言书 [第 4 版] 的第 6.4.1 节在讨论值类别时指出:

可移动:对象可以被移动(即,我们可以将它的值移动到另一个位置,并使对象处于有效但未指定的状态,而不是复制。

题:

  1. “将其价值转移到另一个位置”的真正含义是什么?
  2. 如何移动值(位解释)?
  3. 如何在没有副本的情况下“移动”对象的字节?只是没有意义。

有人可以解释一下吗?

How*_*ant 8

  1. “将其价值转移到另一个位置”的真正含义是什么?

这意味着,其他位置有原来有前移动的价值,认为这并不重要移动后原来的位置有什么价值。

  1. 如何移动值(位解释)?

例如,简单地通过复制。如果想要做更多的工作(这不是仅仅用一袋位来激励的),可以将原始位置设置为其他位模式,例如全零,这仍然会被认为是一次成功的移动。与复制的不同之处在于副本应保持原件不变。

  1. 如何在没有副本的情况下“移动”对象的字节?只是没有意义。

复制是有效的移动。

有时,原始中的位具有拥有资源的语义。如果只有一个资源,并且您只需复制这些位,那么现在两个位置都“拥有”该资源,从而导致当两个对象都超出范围时重复处理所述资源。

因此,移动会将资源的所有权转移到新位置,并将原始位置更改为不拥有资源。一个具体的例子是拥有指针:复制指针然后将原始指针设置为nullptr


副本可能比移动更昂贵(也可能不会)。但是继续拥有指针的例子:如果你复制那个对象,那么在复制之后,两个资源必须存在(假设资源的唯一所有权)。

所以副本不会复制指针。副本复制资源,然后新位置指向新资源。如果该资源的创建成本高昂,那么只需复制指针并将原始指针置空,移动就会便宜得多。


一般来说,当类型支持这两种操作时,移动应该是复制的优化。移动永远不应该比复制更昂贵。如果移动的开销与复制相同,则可以简单地不执行移动操作,复制将无缝处理移动。维护这种范式取决于每种类型的作者。

对于标量(整数、指针、双精度数等),复制和移动是一回事:复制位,不要改变源。