条款10:令operator=返回一个reference to *this
- 为了实现“连续赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参,这是你为classes实现赋值操作符时应该遵循的协议
Widget& operator=(const Widget& rhs){
...
return *this;
}
- 这个协议不仅适用于以上标准赋值形式,也适用于所有赋值相关运算(如+=)
请记住:
- 令赋值(assignment)操作符返回一个reference to this。
条款11:在operator=中处理“自我赋值”
class Bitmap{...};
class Widget{
...
private:
Bitmap*pb;
};
Widget&Widget::operator=(const Widget&rhs){
delete pb;
pb=new Bitmap(*rhs.pb);
return *this;
}
如果发生自我赋值,则rhs.pb指向了一个已经被删除的对象
Widget&Widget::operator=(const Widget&rhs){
if(this->pb==rhs.pb) return *this;
delete pb;
pb=new Bitmap(*rhs.pb);
return *this;
}
解决了自我赋值安全性的问题,但仍不具备异常安全性:若new Bitmap导致异常,则pb指向一块被删除的Bitmap
- 具备异常安全性的版本(往往自动获得自我赋值安全的回报):
Widget&Widget::operator=(const Widget&rhs){
Bitmap*temp=pb;
pb=new Bitmap(*rhs.pb);
delete temp;
return *this;
}
就算new Bitmap抛出异常,pb仍保持原状
- copy and swap技术(不但”异常安全“且”自我赋值安全“):
class Widget{
...
void swap(Widget&rhs);
...
};
Widget&Widget::operator=(const Widget&rhs){
Widget temp(rhs);
swap(temp);
return *this;
}
请记住:
- 确保当对象自我赋值时operator=有良好的行为。其中技术包括比较”来源对象“和”目标对象“的地址(证同测试)、精心周到的语句排序,以及copy-and-swap。
- 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。
|