Effective C++之条款10、11:operator=操作符

声明:

  1. 文中内容收集整理自《Effective C++(中文版)第三版》,版权归原书所有。
  2. 本内容在作者现有能力的基础上有所删减,另加入部分作者自己的理解,有纰漏之处敬请指正。

条款10:令operator=返回一个reference to *this

Have assignment operators return a feference to *this.

请记住:

令赋值(assignment)运算符返回一个reference to *this。

条款11:在operator=处理“自我赋值”

Handle assignment to self in operator=.

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

class Widget{...}
Widget w;
...
w = w; //赋值给自己
//潜在的自我赋值
a[i] = a[j];
*px = *py;

要阻止自我赋值,传统的做法是在operator=最前面加一个“证同测试”达到“自我赋值”的检验目的:

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

但以上代码仍不具备“异常安全性”,如果new Bitmap导致异常,Widget最终会持有一个指针指向一块被删除的Bitmap。

令人高兴的是,让operator=具备“异常安全性”,往往自动获得“自我赋值安全”回报。把焦点放在实现“异常安全性”上,注意在复制pb所指的东西之前别删除pb。

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

现在如果new Bitmap抛出异常,pb能够保持原状。而且还能够处理自赋值。

当然,还有更好的替代方案,那就是“copy and swap技术”。

class Bitmap{...}
class Widget
{
	...
	void swap(Widget& rhs); //交换*this和rhs的数据
	...
private:
	Bitmap* pb;
}
Widget& Widget::operator=(Widget rhs)
{
	//by value传递参数,rhs为局部变量,函数结束后自动调用析构函数销毁
	swap(rhs);
	return *this;
}

请记住:

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值