Функциональные блоки try / catch не одобряются так же, как и goto - может быть какой-то угловой случай, когда они имеют смысл, но их лучше избегать: когда не удается построить объект, лучше всего сделать терпит неудачу и терпит неудачу быстро.
По конкретным вопросам, когда в конструкторе выдается исключение, все полностью построенные подобъекты будут уничтожены. Это означает, что в случае b
он будет уничтожен, в случае c
, который является необработанным указателем, ничего не делается. Самое простое решение - изменить c
на интеллектуальный указатель, который обрабатывает выделенную память. Таким образом, если d
сгенерирует, умный указатель будет уничтожен, а объект освобожден. Это не связано с блоком try / catch, а скорее с тем, как работают конструкторы.
Также, как правило, небезопасно удалять указатель из блока catch, так как нет гарантии действительного значения указателя до инициализации. То есть, если b
или c
throw, это может быть случай, когда c
не равен 0, но также не является допустимым указателем, и удаление его будет неопределенным поведением. Как всегда, бывают случаи, как если бы у вас была гарантия того, что ни b
, ни c
не будет выброшено, и если предположить, что bad_alloc
не является чем-то, от чего вы обычно восстанавливаетесь, тогда это может быть безопасно.
Обратите внимание, что если по какой-то конкретной причине вам нужно сохранить указатель с необработанным указателем, лучше инициализировать его 0 в списке инициализации, а затем создать объект внутри строительного блока, чтобы избежать этой проблемы. Помните также, что наличие более одного (необработанного) ресурса непосредственно в классе делает очень трудным гарантировать, что ни один ресурс не будет пропущен - если первый ресурс создан и назначен, а второй отказывает, деструктор не будет вызван, а ресурс будет течь. Опять же, если вы можете использовать умный указатель, у вас будет на одну проблему меньше.