c++ - 在重载运算符 = 中处理自分配和异常时如何释放内存
问题描述
我正在检查 Scott Meyers 中的 Operator= 过载
Widget& Widget::operator=(const Widget& rhs)
{
Bitmap *pOrig = pb; // remember original pb
pb = new Bitmap(*rhs.pb); // point pb to a copy of rhs’s bitmap
delete pOrig; // delete the original pb
return *this;
}
假设行 pb = new Bitmap(*rhs.pb); // 将 pb 指向 rhs 位图的副本
给出一些异常(可能是由于内存不足)
然后我删除 pOrig [它将释放 pOrig 持有的内存并调用位图析构函数] 那么在此之后,pb 不会指向已删除的指针吗?
解决方案
不,如果new
失败,写入pb
不会发生,因为new
抛出而不是返回。
当您调用一个函数时,该函数将在寄存器上返回一个值。
所以,你会得到类似的东西:
call NewBitmap // From within here, you go directly to the catch clause if any
retval -> pb // <<-- this doesn't get executed
delete pOrig // <<-- this doesn't get executed either
*this -> retval // <<-- this either, you don't return, you rethrow as you don't have a catch
想一想:一旦你有了一个值,你只会写到 pb 。一旦 NewBitmap 返回一个值,您将获得一个值。如果它抛出将不会返回值。
无论如何,这变成了一个反问的问题,因为如果new
失败,继续执行程序不是一个好主意。
推荐阅读
- php - $_POST 只触发一次。我怎样才能不断地监听和处理来自按钮的输入?
- amazon-cloudwatch - 基于 IoT 传感器数据创建自定义 cloudwatch 指标
- sql - 查找重叠的多行之间的总持续时间(以分钟为单位)
- matlab - Matlab:过滤时间表以平衡面板数据
- serialization - 如何定义 yaml 序列映射序列化样式?
- mongodb - 在数字上使用 $regexMatch 和 $expr 时的奇怪行为(mongodb)
- go - 使用 golang docker 映像时无法覆盖 go module protoc 版本
- ethereum - 从 Solidity 中检索变量值
- angular - 使用 TypeScript 在 Angular 中迭代对象的正确方法是什么?
- c - 请解释为什么这个 C 代码给我一个分段错误?