我正在阅读一本推荐的 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/