在赋值运算符中处理自我赋值问题
自我赋值发生在对象被赋值给自己时,例如:
val = val;
vec[i] = vec[j];//潜在的自我赋值(i=j)
*p = *q;潜在自我赋值
class A
{
A& operator=(const A& rhs)//不安全的赋值版本
{
delete p;//停止使用当前的对象
p = new P(rhs.p);//使用rhs的副本
return *this;
}
B p;
}
解决方案一:使用证同测试
A& operator=(const A& rhs)
{
if(this == &rhs) return *this; //证同测试
delete p;//停止使用当前的对象
p = new B(rhs.p);//使用rhs的副本
return *this;
}
这一版本存在异常安全性,如果new发生异常或者B使用copy构造异常,A最终会持有一个指针指向一块被删除的B
解决方案二:记住原先的对象
A& operator=(const A& rhs)
{
B *pp = p;//记住原先的p
p = new B(rhs.p);//另p指向一个*p的副本
delete pp;//删除原先的p
return *this;
}
生命在于折腾,生活就是如此的丰富多彩