【问题标题】:Why using swap to implement copy assignment?为什么要使用swap来实现copy assignment?
【发布时间】:2023-03-21 21:24:01
【问题描述】:

在这里: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 将数据与临时交换。为什么我们要创建一个临时的和交换?只是复制不是更快吗?我在其他地方也看到了这个,很困惑。

【问题讨论】:

    标签: c++


    【解决方案1】:

    交换技巧是确保exception safety 的一种相当简单的方法。

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

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

    【讨论】:

    • 但是在链接的例子中,他们没有使用这个交换来复制构造函数。为什么?
    • @texasbruce:构造函数不同。如果在构造函数中途抛出异常,部分构造的对象将在异常向上传播调用堆栈之前自动正确销毁。
    【解决方案2】:

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

    Foo& operator= (Foo other) { 
      std::swap(data, other.data); 
      return *this;
    }
    

    【讨论】:

    • @texasbruce 复制省略或移动将在“其他”的构造中
    • 我明白了.. 当您传递参数时,对吗?它很聪明,但为什么没有很多人使用这种方法?
    【解决方案3】:

    这是为了避免不一致的状态,或者更准确地说是为了让异常安全。

    您也可以查看此相关主题:- What is the copy-and-swap idiom?

    正如 GManNickG 在上面的帖子中提到的那样:-

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

    为了使用复制和交换习语,我们需要三件事: 工作拷贝构造函数,工作析构函数(两者都是 任何包装器,所以无论如何都应该是完整的),以及一个交换功能。

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

    同时检查Why do some people use swap for move assignments?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多