为什么重载操作符=使异常安全
why does overload operator= makes exception safety
非常直接的问题。
class Bitmap {...};
class Widget {
...
private:
Bitmap* pb;
};
重载拷贝赋值时,书(Effective c++)中说:以下代码是异常安全的。
Widget& Widget::operator=(const Widget& rhs) {
if (rhs == *this) return;
Bitmap* pOrig = pb; //?? why remember the pb can do exception safety?
pb = new Bitmap(*rhs.pb);
delete pOrig;
return *this;
}
书中说:即使通过新的位图(*rhs.pb)遇到异常,上面的代码能做到异常安全,pb能保持不变,指针不指向NULL吗?但是怎么做,为什么?有人能帮我吗?谢谢!
虽然这个问题可能不太精确,但我认为我仍然明白了要点:
想象一下,代码应该写成如下:
Widget& Widget::operator=(const Widget& rhs)
{
if (rhs == *this) // actually, you'd rather do &rhs == this!
// you don't want self-assignment
return;
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
会发生什么,如果new Bitamp()
异常失败-那么pb已经被删除-并指向无效内存!
首先记住pb的值,如果创建异常失败,则没有修改this
,即使发生异常,它仍然有效。
如果在new Bitmap(*rhs.pb)
的构造过程中抛出异常,则Widget
的状态仍然保持不变。
如果在做new Bitmap(*rhs.pb)
之前先删除pb
:
Widget& Widget::operator=(const Widget& rhs) {
if (rhs == *this) return;
delete pb; // unsafe
pb = new Bitmap(*rhs.pb);
return *this;
}
和new Bitmap(*rhs.pb)
失败(抛出异常),在Widget
中没有Bitmap
实例,pb
指向Bitmap
的删除实例。这将在销毁Widget
时崩溃
相关文章:
- C++代码中的异常安全
- 编写"anti-lack of memory"异常安全代码
- std:string::substr 异常安全吗?
- 如何以异常安全的方式使用放置新?
- 异常安全服务器
- 实现 std::vector::p ush_back 强异常安全
- 标准::unique_ptr和异常安全
- 如何使用QThreads使无锁生产者-消费者线程交换更加异常安全
- 使功能异常安全
- 与构造函数参数相关的异常安全的习语
- uninitialized_copy() 异常安全吗?
- 为什么我们需要 RAII 来解决异常安全问题
- 异常安全构造函数
- 关于 swap() 操作的异常安全 - 这有什么问题?
- std::vector::擦除异常安全
- 异常安全 - 用于可靠回滚对象状态的模式
- 异常安全的 for 循环
- 异常安全代码和移动语义
- 向量::插入的异常安全保证是什么?
- 异常安全和make_unique