条款11:记得在operator=中处理自赋值的情况。

本来的版本是这样的:

1 Widget & Widget::operator=(Widget rhs)
2 {
3     delete pb;//这里可能直接将rhs的pb删除了
4     pb = new (*rhs.pb);
5     return *this;
6 }

这里的代码完全无法处理自赋值的情况,一般是在operator的真正处理之前加上一个“证同测试”,像下面这样:

 1 Widget& Widget::operatpr=(const Widget & rhs)
 2 {
 3     if(*this == rhs)
 4         return *this;
 5     else
 6     {
 7         delete pb;//pb是对象中的一个指针
 8         pb = new(*rhs.pb);
 9         return *this;
10     }
11 }

其实下面这种做法更好,因为上面的情况如果在new的时候抛出异常带来的伤害会比较大。

Widget& Widget::operator=(const Widget & rhs)
{
    Bitmap *pOrig = pb;
    pb = new Bitmap(*rhs.pb);//这样做的好处就是不用担心在new的时候会产生什么伤害。
    delete pOrig;
    return *this;//这里经过了精心的调整顺序
}

还有一种方式采用所谓的copy and swap技术;

Widget & Widget::operator=(Widget rhs)
{
    Widget temp(rhs);
    swap(temp);
    return *this;
}

小结:确保当对象自我赋值的时候有较好的行为,基本的技术包括:比较来源对象与目的对象的地址, 精心的调整语句顺序, 以及copy-and-swap技术。

posted @ 2015-10-05 15:15  eversliver  阅读(206)  评论(0编辑  收藏  举报