Проходя через Effective C ++ (автор Скотт Мейерс), я наткнулся на следующий код, который автор использует для иллюстрации того, как следует обрабатывать исключения при копировании элементов данных из одного объекта в другой.
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;
}
В случае, если «новое растровое изображение» выдает исключение, 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;
}
Что (он утверждает) является плохим, потому что, когда «новое растровое изображение» выдает исключение (либо из-за недостатка памяти для выделения, либо из-за того, что конструктор копирования растрового изображения выдаетво-первых, виджет будет содержать указатель на удаленное растровое изображение
Я проверил ошибки в книге, но не нашел упоминания об этом примере.Я что-то упускаю из виду?Кроме того, кто-то может предложить лучший способ обработки этого исключения?