Очевидно, что завершать программу при каждом обнаружении ошибки попросту неприемлемо. Здесь мы согласны со Страуструпом. В таких случалх следует поступать более изобретательно. Что касается варианта 2, то примитивный возврат значения ошибки действительно может помочь в некоторых ситуациях, но далеко не во всех. Не каждое возвращаемое значение может интерпретироваться как успешное или неудачное. Например, если значение, возвращаемое некоторой функцией, имеет вещественный тип, и область определения функции включает как отрицательные, так и положительные значения, то какое тогда значение функции можно использовать для представления ошибки? Другими словами, это не всегда возможно. С нашей точки зрения, вариант 3 также неприемлем. Ведь если «изготовитель» возвращает значение, обозначающее нормальное завершение, «потребитель» продолжит работу, предположив, что его запрос был выполнен, а это может вызвать еще большие проблемы. Осталось рассмотреть вариант 4. Он требует более внимательного подхода при обсуждении обработки как ошибок, так и исключительных ситуаций.
План А: модель возобновления, план Б: модель завершения
При обнаружении ошибки или исключительной ситуации существует два основных плана для реализации варианта4. Первый план состоит в попытке скорректировать условия, которые вызвали сбой, а затем возобновить выполнение с точки, в которой была обнаружена ошибка или исключительнал ситуация. Этот подход называетс
Использование объектов отображения для обработки ошибок
Компонент отображения (map) можно использовать как составную часть стратегии обработки ошибок или обработки исключений. Назначение отображения — связать один элемент с другим. Например, отображение можно использовать для связи номеров ошибок с их описаниями:
//.. .
map
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
defect_response * Response;
Response = new defect_response;
ErrorTable[123] = Response;
//...
Этот код связывает объект отклика (на ошибку) с номером ошибки 123. Благодаря полиморфизму объект отображения может содержать указатели на любой объект типа defect_response или любой объект, который выведен из него. Предположим, что у нас есть следующий класс:
class exception_response : public defect_response{
//.. . public:
int doSomething(void)
//...
};