Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Лафоре Р. -> "Объектно-ориентированное программирование в С++" -> 251

Объектно-ориентированное программирование в С++ - Лафоре Р.

Лафоре Р. Объектно-ориентированное программирование в С++ — М.: Питер, 2004. — 992 c.
Скачать (прямая ссылка): obektnoorentprogramm2004.djvu
Предыдущая << 1 .. 245 246 247 248 249 250 < 251 > 252 253 254 255 256 257 .. 341 >> Следующая


Обработчик ошибок (улавливающий блок)

Код, в котором содержатся операции по обработке ошибок, заключается в фигурные скобки и начинается с волшебного слова catch. Имя класса исключений должно включать в себя наименование класса, в котором он живет. В данном примере это Stack::Range.

catch(Stack::Range) {

//код-обработчик ошибок }

Такая конструкция называется обработчиком прерываний. Она должна следовать непосредственно за блоком повторных попыток. Что касается приведенного примера, то в нем обработчик ошибок занимается только выводом на экран сообщения об ошибках, чтобы пользователь знал, почему его программа перестала работать. Управление программой «проваливается» на дно обработчика ошибок, так что программа может продолжать работу прямо с этого места. Обработчик, правда, может передать управление совсем в другое место, а еще чаще он поступает совсем просто: завершает работу программы.

Последовательность событий

Давайте подведем итоги и покажем последовательность действий программы при возникновении ошибки.

1. Код нормально выполняется вне блока повторных попыток.

2. Управление переходит в блок повторных попыток.

3. Какое-то выражение в этом блоке приводит к возникновению ошибки в методе.

4. Метод генерирует исключение.

5. Управление переходит к обработчику ошибок (улавливающему блоку), следующему сразу за блоком повторных попыток.

Вот и все. Обратите внимание, каким прозрачным и четким получился конечный алгоритм. В любом выражении блока повторных попыток может произойти ошибка, но у нас все под контролем, не нужно беспокоиться о получении возвращаемого значения для каждого из них, потому что это делается автоматиче- 666

Глава 14. Шаблоны и исключения

ски. В данном конкретном примере мы сознательно написали два ошибочных выражения. Первое:

si.push(44); //в стек занесено слишком много элементов

приводит к исключительной ситуации (если в примере убрать комментарии перед ним), а второе:

cout « "4: " « sl.popO « endl; //извлечение из пустого

//стека

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

Исключение: Стек переполнен или пуст

Многократные исключения

Можно спроектировать класс таким образом, чтобы он генерировал столько исключений, сколько нужно. Чтобы показать, как это делается, мы изменим программу XSTAK таким образом, чтобы она выдавала отдельные исключения при попытке переполнения стека и попытке извлечения из пустого стека.

Листинг 14.9. Программа XSTAK2 v

// xstak2.cpp "fi

// Демонстрация обработчика двух исключений !include <iostream> using namespace std;

const int MAX = 3; //в стеке может быть до трех целых чисел ///////////////////////////////////////////////////////////

class Stack {

private;

int st[MAX]; //стек: массив целых чисел

int top: //индекс верхушки стека

public:

class Full { }; //класс исключения class Empty { }; //класс исключения

//.........................................................

StackO //конструктор

{ top - -1; }

//.........................................................

void pushdnt var) //занести число в стек {

іf(top >- MAX-I) //если стек полон,

throw Full О; //генерировать исключение Full

st[++top] - var; }

//.........................................................

int рорО //взять число из стека

, {

1f(top < 0) //если стек пуст,

throw EmptyO; //генерировать исключение Empty return st[top--]: Исключения 667

}

}:

///////////////////////////////////////////////////////////

int mainO {

Stack si;

try {

sl.push(ll); sl.push(22): sl.push(33):

// sl.push(44): //Опаньки: стек уже полон

cout « "1: " « sl.popO « endl: cout « "2: " « sl.popO « endl; cout « "3: " « sl.popO « endl; cout « "4: " « sl.popO « endl:

//Опаньки: стек пуст

}

catch(Stack:: Full) {

cout « "Ошибка: переполнение стека" « endl: }

catch(Stack:: Empty) {

cout « "Ошибка: стек пуст" « endl: }

return 0: }

В этой программе были описаны два класса исключений:

class Full { }: class Empty { }:

Выражение

throw Full О;

исполняется, если программа вызывает push() при уже заполненном стеке, а throw EmptyO;

исполняется, если программа вызывает рор() при пустом стеке.

Для каждого исключения используется отдельный отлавливающий блок:

try

{

//код, работающий с объектами класса Stack

}

catch {

//код обработки исключения Full }

catch

{

//код обработки исключения Empty } 668

Глава 14. Шаблоны и исключения

Все отлавливающие блоки, используемые с конкретными блоками повторных попыток, должны следовать в коде непосредственно за ними. В этом случае каждое исключение приведет к выводу своего сообщения об ошибке: «Стек заполнен» или «Стек пуст». Даешь каждому отлавливающему блоку по своему исключению! Таков девиз приведенной выше программы, да так, собственно, зачастую и делается в программах. Группа отлавливающих блоков (цепь ловушек) работает примерно как выражение switch в том смысле, что исполняется только один соответствующий блок кода. После обработки исключения управление программой переходит к тому месту программы, которое следует за всеми бло-ками-ловушками. (В отличие от switch, не нужно заканчивать каждый отлавливающий блок break. В какой-то мере эти блоки напоминают функции.)
Предыдущая << 1 .. 245 246 247 248 249 250 < 251 > 252 253 254 255 256 257 .. 341 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100