[Исправление:] Это не так. Исключение в конструкторе не приведет к утечке ресурсов, поскольку единственное место, где может возникнуть исключение, находится внутри выражения new
, а если выражение new
происходит сбой, ресурсы, выделенные им, освобождаются. Ваша ситуация особенная, потому что вы делаете только одно выделение в конструкторе - в общем, это небезопасно!
Обозначенная вами цитата - это оператор удаления для объекта с ошибкой, чейКонструктор Threw:
struct T
{
T() { throw 1; }
char data[200];
};
// in your code:
T * pt = new T;
В последней строке память выделяется до вызова конструктора. Что память освобождается в случае исключения автоматическим вызовом ::operator delete(pt)
.(Как правило, вызывается соответствующий оператор удаления (не «выражение»!), Соответствующий новому выражению.)
Это выглядит так:
Обратите внимание, что у нас только есть объект после того, как конструктор завершил - так что в случае исключения вконструктор, , у нас даже нет объекта .Вот почему я сказал «проваленный объект» выше с дефисом, потому что это вообще не объект (как пихта Дугласа вообще не пихта).
Ваш код потенциально полностью утечек unsafe , если вы выполняете более одного выделения, которое может быть выброшено, т. е. возникает утечка всякий раз, когда один объект был успешно построен, но другой, последующий отказывает.Вам, вероятно, следует просто не вызывать new
в списке инициализаторов и вместо этого поместить его в тело:
class Danger
{
T * pt1, * pt2;
public:
Danger()
{
try { pt1 = new T; } catch(...) { throw(); }
try { pt2 = new T; } catch(...) { delete pt1; throw(); }
}
};
Или, по принципу единой ответственности, не используйте необработанные указатели, а используйте контейнеры для управления ресурсамичто убирать за собой !!