Например, если значение, возвращаемое некоторой функцией, имеет вещественный тип, и область определения функции включает как отрицательные, так и положительные значения, то какое тогда значение функции можно использовать для представления ошибки? Другими словами, это не всегда возможно. С нашей точки зрения, вариант 3 также неприемлем. Ведь если «изготовитель» возвращает значение, обозначающее нормальное завершение, «потребитель» продолжит работу, предположив, что его запрос был выполнен, а это может вызвать еще большие проблемы. Осталось рассмотреть вариант 4. Он требует более внимательного подхода при обсуждении обработки как ошибок, так и исключительных ситуаций.

План А: модель возобновления, план Б: модель завершения

При обнаружении ошибки или исключительной ситуации существует два основных плана для реализации варианта4. Первый план состоит в попытке скорректировать условия, которые вызвали сбой, а затем возобновить выполнение с точки, в которой была обнаружена ошибка или исключительнал ситуация. Этот подход называетс я возобновлением. Второй план состоит в признании (подтверждении) ошибки или исключительной ситуации и постепенном выходе из подсистемы или подпрограммы, в которой возникла проблема. Постепенный выход реализуется путем закрытия соответствующих файлов, разрушения требуемых объектов, регистрации (если это возможно) ошибки, освобождения соответствующей памяти и обработки устройств, которые этого требуют. Такой подход называется завершением, и его не следует путать с понятием резкого выхода из программы. Оба плана вполне действенны и в различных ситуациях оказываются весьма полезными. Прежде чем обсуждать способы реализации моделей возобновления и завершения, имеет смысл рассмотреть средства обработки ошибок и исключительных ситуаций, которые прелусмотрены в языке С++.

Использование объектов отображения для обработки ошибок

Компонент отображения (map) можно использовать как составную часть стратегии обработки ошибок или обработки исключений. Назначение отображения — связать один элемент с другим. Например, отображение можно использовать для связи номеров ошибок с их описаниями:

//.. .

map<int,string> ErrorTable;

ErrorTable[123] = «Деление на нуль»;

ErrorTable[4556] = «Отсутствие тонального вызова»;

//. . .

Здесь число 123 связано с описанием «Деление на нуль». Тогда при выполнении инструкции

cout « ErrorTable[123] « endl;

в объект выходного потока cout будет записана строка «Деление на нуль».

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

defect_response:

class defect_response{

protected: //. . .

int DefectNo;

string Explanation;

public:

bool operator<(defect_response &X);

virtual int doSomething(void); string explanation(void);

//...

};

Теперь мы можем внести в отображение объекты типа defect_response:

//...

map<int,defect_reponse *> ErrorTable;

defect_response * Response;

Response = new defect_response;

ErrorTable[123] = Response;

//...

Этот код связывает объект отклика (на ошибку) с номером ошибки 123. Благодаря полиморфизму объект отображения может содержать указатели на любой объект типа defect_response или любой объект, который выведен из него. Предположим, что у нас есть следующий класс:

class exception_response : public defect_response{

//.. . public:

int doSomething(void)

//...

};

Этот класс exception_response является потомко м класса defect_response, поэтому мы можем внести в объект ErrorTable указатели на тип exception_re sponse.

//...

map<int,defect_reponse *> ErrorTable;

defect_response * Response;

exception_response *Response2;

Response = new defect_response;

Respone2 = new exception_response;

ErrorTable[123] = Response; // Хранит объект типа

// defect_response.

ErrorTable[456] = Response2; // Хранит объект типа

// exception_response.

//...

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

//...

defect_response *ProblemSolver;

ProblemSovler = ErrorTable[123];

ProblemSolver->doSomething();

ProblemSovler = ErrorTable[456];

ProblemSovler->doSomething();

//...

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату