证同测试可以解决自我复制的问题。看下面的例子:
Widget&Widget::operator=(const Widget& rhs)
{
delete pb; //这里对pb指向内存对象进行delete,试想如果 this ==& rhs,就是p和rhs指向同一块内存,那就同时把rhs那块内存也delete掉了
pb = new Bitmap(*rhs.pb); //因为上面已经delete 掉了rhs所指的内存,所以这里就不可以new
return *this;
}
也许以下代码能解决以上问题:
Widget& Widget::operator=(const Widget& rhs)
{
if (this ==&rhs)
return*this; //解决了自我赋值的问题。
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
“许多时候一群精心安排的语句就可以导出异常安全(以及自我赋值安全)的代码。”,以上代码同样存在异常安全问题。
Widget& Widget::operator=(constWidget& rhs)
{
Bitmap *pOrig =pb; //记住原先的pb
pb = newBitmap(*rhs.pb); //令pb指向*pb的一个复本
deletepOrig; //删除原先的pb
return *this; //这样既解决了自我赋值,又解决了异常安全问题。自我赋值,将pb所指对象换了个存储地址。
}