C++中赋值函数operator=潜在的“自我赋值安全性”和“异常安全性”

看下面一段代码:

class Bitmap { ... }
class Widget
{
    public:
        Widget& operaotr=(const Widget& wg);
    private:
        Bitmap* bp;
}

Widget& operator=(const Widget& wg)
{
    delete bp;
    bp = new Bitmap(*wg.bp);
    return *this;
}

上面的一段简单的赋值函数,看上去逻辑很正确:首先释放掉bp所指的当前对象,然后将其指向新的对象,并返回指向this的引用。如果仔细分析,会发现存在下面两个问题:

1)如果bp与wg的bp所指的是同一对象,那么delete bp后,wg的bp也将指向一个已经删除的对象,最终bp所指的也是一个已经删除的对象,从而出现错误。

2)如果上面的问题没有出现,但new一个Bitmap的时候出现了异常(内存分配不足或者拷贝构造函数出现异常等),那么最终得到的pb还是指向一个已经删除的对象。

为了解决上面的问题,可以先将bp指向新的对象,然后再释放掉其原来指向的对象。

例如:

Widget& operator=(const Widget& wg)
{
    Bitmap* srbp = bp;
    bp = new Bitmap(*wg.bp);
    delete srbp;
    return *this;
}

或者如下方法,将wg的数据制作一个副本,然后将这个副本数据与*this数据交换。

Widget& operator=(const Widget& wg)
{
    Widget ob(wg);
    swap(ob);
    return *this;
}


整理子Effective C++第3版case 11。

原文链接: https://www.cnblogs.com/sophia-yun/archive/2013/05/10/3071263.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/87898

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午11:20
下一篇 2023年2月9日 下午11:20

相关推荐