• Effective C++ 条款11:在operator=中处理"自我赋值"


    ”自我赋值”发生在对象被赋值给自己时:

    class Widget { ... };
    Widget w;
    ...
    w = w;					// 赋值给自己
    a[i] = a[j];			// 潜在的自我赋值
    *px = *py;				// 潜在的自我赋值
    
    class Base { ... };
    class Derived: public Base { ... };
    void doSomething(const Base& rb, Derived* pd);	// rb和*pd有可能其实是同一对象
    

    尝试自我管理资源

    class Bitmap { ... };
    class Widget {
    	...
    private:
    	Bitmap* pb;			// 指针,指向一个从heap分配而得的对象
    };
    // 一个不安全的operator=实现版本
    Widget& Widget::operator=(const Widget& rhs) {
    	delete pb;						// 停止使用当前的bitmap
    	pb = new Bitmap(*rhs.pb);		// 使用rhs's bitmap的副本
    	return *this;					// 见条款10
    }
    

    可能出现的问题就是,*this和rhs可能是同一个对象,最后会导致自己持有一个指针指向一个已被删除的对象!

    自我安全性

    Widget& Widget::operator=(const Widget& rhs) {
    	if (this == rhs) return *this;			// 证同测试
    											// 如果是自我赋值,就不做任何事情
    	delete pb;
    	pb = new Bitmap(*rhs.pb);
    	return *this;
    }
    

    以上代码确实解决了自我赋值的问题,但是会引发异常的问题,如果new Bitmap导致异常了,那么Widget最终会持有一个指针指向一块被删除的Bitmap。

    异常安全性

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

    copy and swap

    class Widget {
    ...
    void swap(Widget& rhs);
    ...
    };
    Widget& Widget::operator=(const Widget& rhs) {
    	Widget temp(rhs);
    	swap(temp);
    	return *this;
    }
    Widget& Widget::operator=(Widget rhs) {	// 注意这里是传值
    	swap(rhs);					
    	return *this;
    }
    

    总结

    1. 确保当对象自我赋值时operator=有良好行为。其中技术包括比较”来源对象”和”目标对象”的地址、精心周到的语句顺序、以及copy-and-swap.
    2. 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。
  • 相关阅读:
    UML类图图示样例
    在WSSv3中通过Javascript和创建Feature扩展站点的动作菜单
    LINQ之Select各种操作
    TroubleShoot: SharePoint工作流不能自动启动
    TroubleShoot:页面上WebPart显示错误
    ECMAScript对列表项的增删改查
    隐藏SharePoint查看所有内容及回收站
    Windows2000计划任务对机器进行重新启动
    CF576E Painting Edges
    CF1491H Yuezheng Ling and Dynamic Tree
  • 原文地址:https://www.cnblogs.com/zhonghuasong/p/7443800.html
Copyright © 2020-2023  润新知