c++ - 检查 operator= 中的自赋值

标签 c++ operator-overloading

我正在查看 C++ Primer 第五版中的代码示例。在第 512 页上,他们给出了 operator= 的示例代码,如下所示:

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
    auto newp = new string(*rhs.ps); // copy the underlying string
    delete ps;                       // free the old memory
    ps = newp;                       // copy data from rhs into this object
    i = rhs.i;
    return *this;                    // return this object
}

他们正确地争辩说,如果你按这个顺序做事,即使是 self 分配,事情也会很好。但是,我一直看到明确进行检查的建议:

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
    if (&rhs == this) return *this;  // early exit if self assignment

    auto newp = new string(*rhs.ps); // copy the underlying string
    delete ps;                       // free the old memory
    ps = newp;                       // copy data from rhs into this object
    i = rhs.i;
    return *this;                    // return this object
}

这避免了额外的内存分配/释放步骤。

谁能解释为什么他们强调编写处理自赋值的代码而不只是在自赋值时提前退出?

最佳答案

I have always seen the recommendation that the check is done explicitly

您一直在错误的地方寻找,例如参见C++ 编码标准,作者 Sutter & Alexandrescu。

在大多数程序中自赋值是极其罕见的,因此显式检查会为每个自赋值增加少量成本,即使检查几乎总是错误的。如果您编写的赋值运算符即使在自赋值的情况下也是正确的,那么在绝大多数情况下您都不会得到检查的成本,并且如果发生自赋值它仍然有效。

Sutter & Alexandrescu 展示了一个根据 swap 成员编写的赋值运算符:

Foo& operator=(const Foo& other)
{
  Foo(other).swap(*this);
  return *this;
}

这对于自赋值是安全的,异常安全的,并且可以重复使用复制构造函数,因此您不必显式地实现赋值。

关于c++ - 检查 operator= 中的自赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22023485/

相关文章:

c++ - 无法使用 C++ access() 函数访问网络附加存储 (NAS) 中的文件?

c++ - 使用模板模板参数对 'operator<<' 进行模糊重载

c# - c#中有距离、速度、加速度等类库吗?

c++ - “double& Point::operator[](unsigned int)”在此上下文中不可访问

c++ - 在 C++ 中创建 SVG 图像

c++ - ld 找不到可用的库

c++ - 为什么指向非常量成员函数的指针不能指向与常量成员函数相反的指针?

c++ - 这个运算符重载函数返回什么?

c++ - 重载运算符 >>()

c++ - 如何确保 mount 命令在 qt 进程中实际完成