1

在这里:http://en.m.wikipedia.org/wiki/Rule_of_three_(C++_programming)

/** Copy Assignment Operator */ 
Foo& operator= (const Foo& other) { 
  Foo temporary (other); 
  std::swap (data, temporary.data); 
  return *this;
 }

在示例中,它使用std::swap临时交换数据。为什么我们要创建一个临时的和交换?只是复制不是更快吗?我在其他地方也看到了这个,很困惑。

4

3 回答 3

5

交换技巧是确保异常安全的一种相当简单的方法。

如果您进行逐个字段的复制,并在中间出现异常,您的对象最终可能会处于不一致的状态(除非您采取措施解决这个问题,这可能会使事情变得相当复杂)。

使用基于交换的实现,如果Foo temporary (other)抛出,您的对象将保持其原始状态不变。

于 2013-11-09T19:29:44.770 回答
1

此外,要启用复制省略和 (c++11) 移动语义:

Foo& operator= (Foo other) { 
  std::swap(data, other.data); 
  return *this;
}
于 2013-11-09T19:39:27.420 回答
0

这是为了避免不一致的状态,或者更确切地说,我们会说使异常安全。

您也可以查看这个相关的线程:-什么是复制和交换成语?

正如 GManNickG 在上述线程中提到的那样:-

它通过使用复制构造函数的功能来创建数据的本地副本,然后使用交换函数获取复制的数据,将旧数据与新数据交换。然后临时副本销毁,并带走旧数据。我们留下了新数据的副本。

为了使用 copy-and-swap 习惯用法,我们需要三样东西:一个工作的复制构造函数、一个工作的析构函数(两者都是任何包装器的基础,所以无论如何都应该是完整的)和一个交换函数。

交换函数是一个非抛出函数,它交换一个类的两个对象,成员对成员。我们可能会想使用 std::swap 而不是自己提供,但这是不可能的;std::swap 在其实现中使用复制构造函数和复制赋值运算符,我们最终会尝试根据自身定义赋值运算符!

另请检查为什么有些人使用交换进行移动分配?

于 2013-11-09T19:32:51.103 回答