码迷,mamicode.com
首页 > 编程语言 > 详细

Effective C++ Item 11-在operator = 中处理"自我赋值"

时间:2016-08-09 15:04:02      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:

Item 11-在operator = 中处理"自我赋值"(Handle assignment to self in operator = )


"自我赋值"发生在对象被赋值个自己:

Ex1:

class Widget{...};
Widget w;
...
w=w;    //赋值给自己

Ex2:建立一个class用来保存一个指针指向一块动态分配的位图(bitmap)

class Bitmap{...};
class Widget
{
    ...;
    private:
        Bitmap* pb;    //指针,指向一个从heap分配而得的对象
};

下面是实现operator = 实现代码,但自我赋值出现时并不安全

Widget &
Widget::operator = (const Widget& rhs)  //一份不安全的operator = 实现版本
{
    delete pb;
    pb = new Bitmap(* rhs.pb)  //使用rhs’s bitmap的副本
    return *this;
}


如果operator = 函数内的*this和rhs是同一个对象,那么delete就不只是销毁当前对象的bitmap。它也销毁rhs和bitmap,return就会指向一个被删除的对象。


解决方案

1、operator = 最前面的一个"证同测试"(identity test)

Widget& Widget::operator = (const Widget& rhs)
{
    if(this = &rhs)
        return *this      // identity test
    delete pb;
    pb = new Bitmap(* rhs.pb)
    return *this;
}

2、复制一份再删除

Widget& Widget::operator = (const Widget& rhs)
{
    Bitmap* pOrig = pb;   //记住原先的pb
    pb = new Bitmap(*rhs.pb);   //令pb指向*pb的一个复件
    delete pOrig;     //删除原先的pb
    return *this;
}

3、确保代码不但"异常安全"而且"自我赋值安全",copy and swap技术

class Widget
{
    ...
    void swap(Widget& rhs);   //交换*this的rhs的数据
};
Widget& Widget::operator = (const Widget& rhs)
{
    Widget temp(rhs);   //为rhs数据制作一份复件
    swap(temp);         //将*this数据和上述复件的数据交换
    return *this;
}

请记住:

确保当对象自我赋值时operator = 有良好行为。其中技术包括比较"来源对象"和"目标对象"的地址,精心周到的语句顺序,以及copy and swap。

确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。


Effective C++ Item 11-在operator = 中处理"自我赋值"

标签:

原文地址:http://blog.csdn.net/u011391629/article/details/52161029

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!