【复读EffectiveC++11】条款11:在operator=中处理“自我赋值”

文章探讨了如何在C++中安全地实现operator=,避免自我赋值时的内存问题和异常影响。方法包括传统检查、升级版复制策略和copyandswap技术,强调异常安全性和正确处理自我赋值情况。
摘要由CSDN通过智能技术生成

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

此条款,同上一条一样,也是针对operator= 的,同样套用两步走说完:

  • 问题现象
  • 怎么解决

一、问题现象

原书中的先是提出了一个现象:
假设建立一个class 用来保存一个指针指向一块动态分配的位图。

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

上面是一份不安全的 operator= 实现版本,因为 operator= 函数内的*this 和 rhs 有可能是同一个对象。

二、怎么解决

1、传统方法

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

传统方法,也是最简单的方法,是在重载赋值方法的第一步先检验一下传入对象是否为自己。
但这种方法并不是“异常安全的”。

例如在new操作符执行时跑出了异常(内存不足或因为Bitmap类的拷贝构造函数抛出异常),最终Widget对象会只有一个一块已被删除的Bitmap,因此代码是不安全的。

2、升级版

Widget&  Widget::operator= (const Widget& rhs)
 {
     Bitmap* pOrig = pb ;

     pb = new Bitmap(*rhs.pb);
     delete pOrig ;
     return *this;
 }

这段代码可以来处理异常:如果new时抛出了异常,此时我们的pb对象还没有删除

这段代码还可以来处理“自我赋值”:我们对原bitmap做了一份复制、删除原bitmap,然后将pb再指向于复制的那一份。这个虽然不是处理“自我赋值”最高效的办法,但是行得通。

3、copy and swap 技术

替换上面的所有办法,我们可以使用“copy and swap”技术来解决“自我赋值”以及“异常处理”copy and swap技术和“异常安全性”有密切关系,会在条款29详细讲述

Widget&  Widget::operator= (const Widget& rhs)
 {
      Widget temp( rhs ) ;
      swap(temp);

      return *this;
 }

三、总结

确保当前对象自我赋值时operator=有良好行为。其中技术包括比较“来源对象”和“目标对象”的地址、精心周到的语句顺序、以及copy=and-swap
确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值