gpt4 book ai didi

c++ - 处理复制赋值运算符中的异常 (c++)

转载 作者:行者123 更新时间:2023-11-30 04:28:45 26 4
gpt4 key购买 nike

在学习 Effective C++(Scott Meyers 着)时,我遇到了以下代码,作者使用这些代码来说明在将数据成员从一个对象复制到另一个对象时应如何处理异常。

class Bitmap { ... };

class Widget {
...

private:
Bitmap *pb; // ptr to a heap-allocated object
};

Widget& Widget::operator=(const Widget& rhs)
{
Bitmap *pOrig = pb; // remember original pb
pb = new Bitmap(*rhs.pb); // make pb point to a copy of *pb
delete pOrig; // delete the original pb
return *this;
}

如果“new Bitmap”抛出异常,pb将保持不变。但是,通过删除pOrig,pb指向的内存已经被释放。这不危险吗?它比下面的代码好在哪里

Widget& Widget::operator=(const Widget& rhs)

{
if (this == &rhs) return *this; // identity test: if a self-assignment,
// do nothing
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}

(他声称)这很糟糕,因为当“新位图”产生异常时(因为没有足够的内存用于分配或因为位图的复制构造函数抛出异常),Widget 最终将持有指向已删除位图的指针

我查了这本书的勘误表,但没有提到这个例子。我错过了一些明显的东西吗?另外,有人可以建议一种更好的方法来处理此异常吗?

最佳答案

当且仅当 pb = new Bitmap(*rhs.pb); 成功时,delete pOrig; 才会执行。如果分配失败,则不再执行此构造函数——相反,堆栈将展开,执行将从 Bitmap 构造函数抛出异常的任何部分直接转到抛出任何异常的处理程序。沿途唯一的一站是销毁 ctor 的局部变量,但由于唯一的局部变量是一个指针,销毁它几乎是一个 nop。

在 Widget 对象包含任何其他成员变量的情况下,任何已完全构建的成员变量也将作为堆栈展开的一部分被销毁,但由于它没有任何(显示)与此处无关。

关于c++ - 处理复制赋值运算符中的异常 (c++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9865822/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com