Язык программирования C++ для профессионалов



         

Производные особые ситуации - часть 2


void h() { try { // какие-то операторы } catch (Matherr) { if (can_handle_it) { // если обработка возможна, // сделать ее } else { throw; // повторный запуск перехваченной // особой ситуации } } }

Повторный запуск записывается как оператор throw без параметров. При этом снова запускается исходная особая ситуация, которая была перехвачена, а не та ее часть, на которую рассчитан обработчик Matherr. Иными словами, если была запущена Int_overflow, вызывающая h() функция могла бы перехватить ее как Int_overflow, несмотря на то, что она была перехвачена в h() как Matherr и запущена снова:

void k() { try { h(); // ... } catch (Int_overflow) { // ... } }

Полезен вырожденный случай перезапуска. Как и для функций, эллипсис ... для обработчика означает "любой параметр", поэтому оператор catch (...) означает перехват любой особой ситуации:

void m() { try { // какие-то операторы } catch (...) { // привести все в порядок throw; }

}

Этот пример надо понимать так: если при выполнении основной части m() возникает особая ситуация, выполняется обработчик, которые выполняет общие действия по устранению последствий особой ситуации, после этих действий особая ситуация, вызвавшая их, запускается повторно.

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

try { // ... } catch (ibuf) { // обработка переполнения буфера ввода } catch (io) { // обработка любой ошибки ввода-вывода } catch (stdlib) { // обработка любой особой ситуации в библиотеке } catch (...) { // обработка всех остальных особых ситуаций }

Тип особой ситуации в обработчике соответствует типу запущенной особой ситуации в следующих случаях: если эти типы совпадают, или второй тип является типом доступного базового класса запущенной ситуации, или он является указателем на такой класс, а тип ожидаемой ситуации тоже указатель (§R.4.6).

Поскольку транслятору известна иерархия классов, он способен обнаружить такие нелепые ошибки, когда обработчик catch (...) указан не последним, или когда обработчик ситуации базового класса предшествует обработчику производной от этого класса ситуации (§R15.4). В обоих случая, последующий обработчик (или обработчики) не могут быть запущены, поскольку они "маскируются" первым обработчиком.




Содержание  Назад  Вперед