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

探讨C++中自我赋值与异常安全性的实现,通过对比不同代码段,介绍如何避免自我赋值陷阱和处理异常,确保资源管理的安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自行管理资源时,可能在停止使用资源之前意外释放了它。

class Data{...};
class Widget{
	...
private:
	Data* pd;
};
Widget& Widget::operator=(const Widget& rw)
{
	delete pd;
	pd = new Data(*rw.pd);
	return *this;
}

operator=函数内的*this和rw可能是同一对象,结果就是Widget对象持有一个指针指向一块已被删除的Data。

  • 自我赋值安全性
  • 异常安全性

添加证同测试:

Widget& Widget::operator=(const Widget& rw)
{
	if(this == &rw) return *this;
	delete pd;
	pd = new Data(*rw.pd);
	return *this;
}

如果"new Data"导致异常(内存不足或copy构造抛出异常),结果和上面一样。

  • 自我赋值安全性
  • 异常安全性

一般情况下,让operator=具备“异常安全性”往往自动获得“自我赋值安全性”

Widget& Widget::operator=(const Widget& rw)
{
	Data* tmp = pd;
	pd = new Data(*rw.pd);
	delete tmp;
	return *this;
}

delete 延后,如果"new Data"导致异常,pb将保持原状。

在operator=函数内手工排列语句的一个好的替代方案是使用,copy and swap技术,条款29。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值