- •ИСКЛЮЧЕНИЯ. СПЕЦИФИКАЦИЯ ИСКЛЮЧЕНИЙ
- •Любое необработанное исключение приводит к вызову функции terminate(), которая
- •Обработка ошибок
- •Пример. Обработка выхода за границы массива с помощью исключения
- •int& operator[](int i); int size(){return sz;}
- •int main() {
- •2) возвратить значение, трактуемое как "ошибка";
- •Вариант [2] можно реализовать не всегда, поскольку не всегда удается определить значение "ошибка".
- •Механизм особых ситуаций можно рассматривать как динамический аналог механизма контроля типов и проверки
- •Пример. Обработка двух исключений
- •Vector::Vector(int s) {
- •catch (Vector::Range) {
- •Примечание. Особые ситуации можно перехватывать в одной функции, можно в разных.
- •Передача данных при
- •class Range { public:
- •void f(int s, int i) { try {/*…*/}
- •2. Поддерживается окончательная модель обработки. Это означает, что после
- •5.Если обработчик «поймал» исключение, то обработка этого же исключения другими обработчиками, которые могут
- •Иерархия исключений
- •void f2() {
- •int main() { f2(); return 0;
- •int formula(int x, int y) {
- •int main() {
- •Особые ситуации могут быть членами нескольких групп.
- •void f3() {
- •int main() { f3(); f4();
ИСКЛЮЧЕНИЯ. СПЕЦИФИКАЦИЯ ИСКЛЮЧЕНИЙ
Исключения являются средством обработки ошибочной ситуации в программе.
Альтернативой исключений является использование переменных (флагов).
В отличие от флагов, состояние которых можно не проверить, на исключения проигнорировать нельзя.
Любое необработанное исключение приводит к вызову функции terminate(), которая
немедленно завершает выполнение программы без вызова деструкторов для локальных и статических объектов.
Генерируется исключение с помощью ключевого слова throw.
Пример. Генерация исключения.
int main() { throw;
cerr << "После исключения\n"; return 0;
}
Обработка ошибок
Обработчиком особой ситуации называется
конструкция:
catch ( /* ... */ ) {/*...*/}
Ее можно использовать только сразу после блока, начинающегося служебным словом try, или сразу после другого обработчика особой ситуации.
После служебного слова catch в скобках задается тип объектов, на которые рассчитан обработчик, и, возможно, имена параметров.
Пример. Обработка выхода за границы массива с помощью исключения
class Vector { int* p;
int sz; public:
Vector(int s=10) {p=new int[sz=s];} class Range {
public:
Range()
{
cerr<<"Error index!!!\n";
}
}; // класс для особой ситуации
int& operator[](int i); int size(){return sz;}
};
int& Vector::operator[](int i) {
if (0<=i && i<sz) return p[i]; throw Range();
}
void f(Vector& v) { try {
v[v.size()+10];
}
catch (Vector::Range) { }
}
int main() {
Vector v; f(v);
return 0;
}
Особые ситуации и традиционная обработка ошибок
Теоретически операция индексации Vector::operator[]() при обнаружении недопустимого значения индекса может выполнить следующие действия:
1) завершить программу;
2) возвратить значение, трактуемое как "ошибка";
3)возвратить нормальное значение и оставить программу в неопределенном состоянии;
4)вызвать функцию, заданную для реакции на такую ошибку.
Вариант [1] реализуется по умолчанию в том случае, когда особая ситуация не была перехвачена. Для большинства ошибок можно и нужно обеспечить лучшую реакцию.
Вариант [2] можно реализовать не всегда, поскольку не всегда удается определить значение "ошибка".
Вариант [3] имеет тот недостаток, что вызывавшая функция может не заметить ненормального состояния программы.
Механизм особых ситуаций успешно заменяет традиционные способы обработки ошибок в тех случаях, когда последние являются неполным или чреватым ошибками решением.
Этот механизм позволяет явно отделить часть программы, в которой обрабатываются ошибки.
Механизм особых ситуаций можно рассматривать как динамический аналог механизма контроля типов и проверки неоднозначности на стадии трансляции.
Механизм особых ситуаций является конструкцией с нелокальной передачей управления и его можно рассматривать как вариант оператора return. Поэтому особые ситуации можно использовать для целей, не связанных с обработкой ошибок.
В программе возможны различные динамические ошибки; с ними можно сопоставить особые ситуации, имеющие различные имена.
Пример. Обработка двух исключений
class Vector { int* p;
int sz; public:
enum { max = 32000 };
class Range { };//особая ситуация индекса class Size { }; // особая ситуация "неверный
размер"
Vector(int sz);
int& operator[](int i); // ...
};