Сначала давайте обсудим вопрос, о котором мы уже упоминали, но на
который пока не дали удовлетворительного ответа: что происходит, когда ошибка
обнаруживается в конструкторе? Например, как будет реагировать
конструктор объекта, когда операция new терпит неудачу из-за того, что не может
выделить требуемой памяти для хранения внутреннего представления объекта?
Поскольку для индикации ошибки конструктор не может возвратить
значение, мы должны найти альтернативное средство для сообщения о том, что
объект не был конструирован должным образом. Одним из возможных путей
может быть возврат неправильно конструированного объекта в надежде на то, что тот, кто собирается с ним работать, произведет соответствующие проверки
и обнаружит, что объект находится в несогласованном состоянии. Другое
решение — установить некоторую переменную вне конструктора. Возможно,
наилучшее решение — потребовать, чтобы конструктор выбрасывал
исключение, содержащее информацию об ошибке, давая программе, таким образом,
|
|
возможность справиться с проблемой.
Исключения, выбрасываемые в конструкторе, приводят к тому, что
вызываются деструкторы для всех объектов, созданных в качестве частей
конструируемого объекта до того, как было выброшено исключение. Вызываются
деструкторы для всех автоматических объектов, конструированных в try-блоке до
исключения. Гарантируется, что к моменту начала исполнения обработчика
исключения разматывание стека будет завершено. Если деструктор,
вызванный в процессе разматывания стека, выбрасывает исключение, вызывается
terminate.
Если объект имеет элементы-объекты, и исключение выбрасывается до
того, как будет завершено конструирование внешнего объекта, то будут
исполняться деструкторы элементов-объектов, уже конструированных к моменту
возникновения исключения. Если к моменту возникновения исключения был
частично конструирован массив объектов, то будут вызваны деструкторы
только для уже конструированных объектов в массиве.
Исключение может воспрепятствовать исполнению кода, который в
нормальной ситуации освобождал бы некоторый ресурс, приводя тем самым
к утечке ресурса. Одним из методов решения этой проблемы является
инициализация локального объекта для доступа к ресурсу. Если возникнет
исключение, для этого объекта будет вызван деструктор, который сможет этот ресурс
освободить.