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

What exactly does it mean to say a C++ object is movable?

给定以下定义:

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

Movable: The object may be moved from (i.e., we are allowed to move its value to another location and leave the object in a valid but unspecified state, rather than copying.

问题:

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

有人可以解释一下吗?

  1. What does "move its value to another location" really mean?

这意味着另一个位置具有原始位置在移动之前的值,并且移动之后原始位置具有什么值并不重要。

  1. How can a value (a bit interpretation) be moved?

例如,简单地通过复制。如果有人想做更多的工作(这不是只用一袋位的动机),可以将原始位置设置为其他一些位模式,例如全零,它仍然被认为是成功的移动。这里与复制的区别在于复制应该保持原件不变。

  1. How can bytes of an object be "moved" without a copy? Just doesn't make sense.

复制是有效的移动。

有时原件中的位具有拥有资源的语义。如果只有 一个 资源,而你只是简单地复制位,现在 两个 位置“拥有”资源,导致重复处理所述资源当两个对象都超出范围时。

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


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

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


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

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

移动对象的行为”类似于“[=25=”的行为]卖房子'。物体保持静止。只有所有权(所有权)易手。

在 C++ 中移动对象的概念是众所周知的“pass-by-reference”方法的实现之一。这可以通过一个真实的例子很容易地解释。

Internet 路由器 是描述移动对象[=31 这一概念的最佳示例之一=].假设具有 4 个接口的路由器通过其中一个接口接收到一个数据包(IP 数据包)。现在,路由器必须在将数据包从其接口之一发送出去之前查找其路由 table、应用安全策略、应用 NAT 规则等。

路由器将只在内存中创建一个数据包副本,并将其引用传递给不同的sub-systems(路由table、NAT、安全、QoS 等)。 路由器的每个 sub-systme 将对数据包进行操作并将其传递给下一个 sub-system,直到数据包从路由器发送到目的地。 当数据包离开路由器时,内存将被清理。

在这种情况下,不同的 sub-systems 路由器在不同时间获得对同一数据包对象的控制权。在整个处理过程中,数据包对象都保留在单个内存位置。它永远不会被复制。这种将对象的所有权传递给不同的sub-systems/函数的方法可以看作是'moving the object'。然而,实际上,对象一直停留在原处,但对象的控制已经移动了sub-systems。

(类似于房屋出售时所有权转移的方式。)