Проектирование графического интерфейса пользователя______________319

4.9.4 Преднамеренная генерация исключений

4.9.4.1 Оператор throw

До сих пор ре'чь шла об исключениях, генерируемых автоматически при вы-
полнении каких-то операций. Но в ряде случаев возникает потребность сгенериро-
вать исключение искусственно. Например, вы обработали какое-то исключение,
но хотите, чтобы его обработка была завершена обработчиком внешнего по отноше-
нию к данному блока try...catch. В этом случае вам надо повторно сгенерировать
исключение того же типа, что и прежнее, поскольку прежнее разрушено данным
обработчиком.

Повторная генерация исключения осуществляется ключевым словом throw.
Общая схема такой двухэтапной обработки исключений может иметь вид:

try

(

// операторы внешнего блока
try // начало внутреннего блока
(

// операторы внутреннего блока,

// способные привести к генерации исключения
!       )

catch(тип исключения &)

L        <

// обработка исключения,сгенерированного во внутреннем блоке
throw; // повторная генерация того же исключения
>
// операторы внешнего блока;

// при генерации исключения не выполняются>
} // завершение внешнего блока try
catch(тип исключения &)

(
I        // обработка исключений и внутреннего, и внешнего блоков

}

При такой организации программы исключения, сгенерированные во внут-
реннем блоке, обрабатываются в два этапа: сначала обработчиком внутреннего бло-
ка, а затем обработчиком внешнего блока. При этом операторы внешнего блока,
следующие за внутренним, при генерации исключения во внутреннем блоке вы-
полняться не будут. Исключения, сгенерированные во внешнем блоке, будут обра-
батываться только обработчиками этого внешнего блока.

С помощью ключевого слова throw можно сгенерировать не только повторное
исключение, но и исключение любого типа в любом месте программы. Такая необ-
ходимость, в частности, возникает, когда пользователь что-то не так сделал и не
имеет смысла продолжать выполнение приложения. Например, пользователь дол-
жен был задать какую-то информацию в окнах редактирования, но забыл это сде-
лать. В этом случае прежде, чем продолжать работу, надо указать пользователю на
его ошибку. Это можно сделать, сгенерировав соответствующее исключение.

Генерация нестандартного исключения производится ключевым словом
throw, после которого указывается генерируемый объект любого типа. Это исклю-
чение может в дальнейшем перехватываться блоком catch, в заголовке которого
указан то же тип, что у сгенерированного объекта. Например, вы можете написать
оператор, который проверяет, задана ли информация в окне редактирования
Editi, и, если не задана, то генерируется исключение:

if(Editl->Text == "") throw "He задана требуемая информация";

В данном случае объект генерируемого исключения имеет тип char *. Подоб-
ных операторов с различными текстами в разных местах кода может быть много.
И все они могут быть перехвачены, например, следующим блоком catch: