Я прав в своем предположении об ошибке в этом операторе присваивания?

Ричард Гиллам в своем «Анатомия оператора присваивания» вероятно, делает неправильное утверждение, когда говорит следующее, только в начале своей статьи:

«Один правильный ответ на этот вопрос будет выглядеть примерно так:»

TFoo&TFoo::operator=(const TFoo& that)
{
if (this != &that)
{
TBar* bar1 = 0;
TBar* bar2 = 0;

try
{
bar1 = new TBar(*that.fBar1);
bar2 = new TBar(*that.fBar2);
}
catch (...)
{
delete bar1;
delete bar2;
throw;
}

TSuperFoo::operator=(that);
delete fBar1;
fBar1 = bar1;
delete fBar2;
fBar2 = bar2;
}
return *this;
}

Я думаю, что автор не прав, потому что если TSuperFoo::operator=() броски, bar1 а также bar2 будет течь.

2

Решение

Не было бы утечки памяти, если бы это выглядело так:

Tbar* pBar = NULL;

try
{
pBar = new Tbar();
}
catch (...)
{
delete pBar;    // clean memory if it was allocated
throw;          // error was not handled properly, throw it to caller
}

delete pBar;        // no exception was caught, clean the memory

Но на тот случай, если до последнего deleteЕсть другой код, который может вызвать исключение, чем вы правы, и действительно существует возможный путь, который приводит к утечке памяти, поскольку в таком случае выделенная память никогда не будет очищена.

Просто печально, что люди пишут код, который не использует замечательные функции, которые предоставляет этот язык, чтобы избежать такого уродливого управления памятью. Обычно достаточно объектов с автоматическим хранением, и вы будете следовать RAII идиома, или в ситуациях, когда динамическое выделение необходимо, тогда хорошей идеей будет обернуть эти голые указатели некоторыми объектами … умные указатели очень помогают.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector