《Effect C++》学习------条款11:在 operator= 中处理“自我赋值”

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

class Widget
{
    ...
};

Widget w;
...
w = w;  //赋值给自己

自我赋值,看起来愚蠢,但是却合法。所有不用认定客户不会这么做。此外赋值动作并不总是那么可被一眼辨别出来,例如:

a[i]= a[j]; //潜在的自我赋值

如果i和j有相同的值,这便是自我赋值。再看:

*px = *py; //潜在的自我赋值

如果px和py恰巧指向同一个东西,这也是自我赋值。这些并不明显的自我赋值,是“别名”带来的结果:

operator=,不仅不具备“自我赋值安全性”,也不具备“异常安全性”。

让operator= 具备“异常安全性”往往自动获得“自我赋值安全性”的回报。因此越来越多的人对“自我赋值”的处理态度是不去管它,而把焦点放在实现“异常安全性”上。

确保代码不但“异常安全”而且“自我赋值安全”的一个替代方案是,使用所谓的copy and swap技术。此技术和“异常安全性”有密切关系,它是一个常见而够好的operator=撰写办法,其实现方式为:

class Widget
{
public:    ...
    void swap(Widget& rhs);     //交换*this和任rhs的数据
    ...
};

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

 另外一种实现方式为:

 ```C++
 Widget& Widget::operator=(Widget rhs)  //rhs是被传对象的一份复件(副本),注意此处是值传递 pass by value
{
    swap(rhs);     //将*this数据和复件的数据交换
    return *this;
}

上述实现方式因为:1、某类的copy assignment操作符可能被声明为“以by value方式接受实参”;2、以by value方式传递东西会造成一份复件/副本

此方式牺牲了清晰性,然而将拷贝动作从函数本体移至“函数参数构造阶段”却可令编译器有时生产更高效的代码

请牢记:

  • [x] 确保当前对象自我赋值时operator= 有良好行为。其中技术包括比较“来源对象”和“目标对象”的地址、精心周到的语句顺心、以及copy-and-swap。

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值