c++ - 分配自身时的复制分配运算符

标签 c++ copy-assignment

我正在阅读一本推荐的 C++ 书籍,在它建议的复制分配部分;

It is cricially important for assignment operator to work correctly, even when object is assigned to itself. A good way to do so is to copy the right-hand operand before destroying the left hand operand.

书中的例子;类有一个数据成员 ps 并且 ps 是字符串 *

C& operator=(const C &rhs)
{
     auto newp = new string(*rhs.ps)
     delete ps;
     ps = newp;
     return *this;        
}

但我们的导师建议

C& operator=(const C &rhs)
{
    if (this == &rhs)
        return *this;

     delete ps;
     ps = new string(*rhs.ps)
     return *this;  
}

导师的做法有没有问题?

最佳答案

您的导师的方法有缺陷。如果 new string(*rhs.ps) 失败,它将抛出异常,这将使 ps 具有无效值(ps 将是指向已删除内存的指针)。

在删除旧数据之前,您必须确保new成功:

C& operator=(const C &rhs)
{
     auto new_ps = new string(*rhs.ps);
     delete ps;
     ps = new_ps;
     return *this;  
}

如果您愿意,您可以防止自赋值,但这不是必需的,并且由于自赋值非常不常见,这样做可能会降低程序的性能。

请记住,如果您有一个自定义的复制赋值运算符,您可能还需要一个自定义的移动赋值运算符、复制构造函数、移动构造函数和析构函数。 (参见 Rule of Five)。

总的来说,这仍然是一个有缺陷的设计。 ps 应该只是一个字符串,或者应该是一个智能指针,例如value_ptr。 .手动管理内存既乏味又容易出错。

关于c++ - 分配自身时的复制分配运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25107821/

相关文章:

数组与标量中的python赋值

c++ - 为什么完美转发(包罗万象)无法实现复制分配?

c++ - DLL注入(inject)后如何获取目标进程的基地址?

c# - 在 .NET 中派生 COM 接口(interface)

c++ - 将外部属性映射附加到图形

c++ - 如何使用 stringstream 分隔逗号分隔的字符串

reference - D 中的赋值操作会复制对象吗?

c++ - 是否推荐具有 copy-and-swap 习语和自赋值检查的复制赋值运算符?

c++ - 传递和分配时保护一些内存

c++ - 在 C++ 中选择错误的文件时防止 boost xml 解析器崩溃