为什么标准在移动赋值算子中使用交换?

时间:2018-03-03 20:54:34

标签: c++

我今天正在尝试使用std :: exchange。根据关于std :: exchange的cppreference page,这个函数可以在移动构造函数和移动赋值运算符中使用。 cppreference的例子是:

struct S
{
  int* p;
  int n;

  S(S&& other)
    :p{std::exchange(other.p, nullptr)}
    ,n{std::exchange(other.n, 0)}
  {}

  S& operator=(S&& other) {
    p = std::exchange(other.p, nullptr); // move p, while leaving nullptr in other.p
    n = std::exchange(other.n, 0); // move n, while leaving zero in other.n
    return *this;
  }
};

我不明白。在移动构造函数中使用std :: exchange是可以的,因为新的(构造的)对象将接管已经存在的(旧)对象的内核,并且旧对象的资源指针将被赋予nullptr值,所以在移动ctor之后,旧对象将被销毁,但资源将继续存在于新对象中。

但是对于移动赋值运算符,它应该以不同的方式工作,我想。受理对象应接管已分配对象的资源,并且分配的对象应接管受理对象的资源。在此之后,当分配的对象被销毁时,它将破坏受让人先前使用的资源。换句话说,该机制应该交换资源。 在此代码中,当分配的对象的资源指针将被分配为nullptr时,我们将泄漏资源(过去在受让人中居住的资源)。我能正确理解吗?或者我错过了什么?

我想还有一些我不知道的东西,因为这个代码用在官方文档中。有人可以帮我理解这里发生了什么吗?

1 个答案:

答案 0 :(得分:5)

首先,没有“官方文件”。 cppreference很受欢迎,但它只是一个网站,也是一个社区编辑的网站。它肯定不是“标准”,并且(像任何网站一样)它包含错误并不是闻所未闻......就像这样。

实际上,这是一个很糟糕的例子 - 不仅资源没有得到正确清理,而且它甚至从未创建过。

您可以使用更好的示例编辑您所引用的页面;它只是一个维基。