Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП на языке С++.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2 Мб
Скачать
☆

5.2. Получение дополнительной информации об исключении

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

Пример 5.2.1

Добавим в класс string вложенный класс range, поле которого i будет хранить значение ошибочного индекса.

struct range

{

int i;

range(int s):i(s){};

};

При ошибке создается объект range,

char& string :: operator[](int s)

{if((s<0)||(s>size)) throw range(s); return p[s];}

Теперь в выражении throw range(s) в поле i объекта класса range будет записано значение ошибочного индекса s.

Для того чтобы в обработчике исключения проанализировать значение ошибочного индекса, необходимо задать имя объекту-индикатору исключения:

try{/* контролируемый код*/}

catch(string : : range ob)

{cerr<<”Неверный индекс: ”<<ob.i<<endl;}

Выражение (string : : range ob) объявляет тип исключения (string : : range) и может дополнительно задавать имя объекта исключения (ob).

Полностью программа выглятит так

#include <iostream.h>

#include<stdio.h>

#include<windows.h>

#include<process.h>

#define ss 20

class string

{

char *p;

int size;

public:

struct range

{int i;

range(int s):i(s){};

};// конец класса range

string(int SIZE){p=new char[size=SIZE];}

~string(){delete[] p;}

char& operator[](int s);

};//конец класса string

char& string :: operator[](int s)

{if((s<0)||(s>size)) throw range(s);

return p[s];}

int main()

{

SetConsoleOutputCP(1251);

int index;

string str(ss);

for(int i=0;i<ss;i++) str[i]='A'+i;

try

{

for(;;) //бесконечный цикл

{cout<<"\nВведите индекс: ";

cin>>index;

cout<<str[index];}

}

catch(string ::range ob)

{cerr<<"Неверный индекс: "<<ob.i<<endl;

}

system("pause");

return 0;

}

Пример 5.2.2

В классе range задается переменная i с атрибутом private, получающая значение ошибочного индекса и две public функции get_index() и index_range(), которые соответственно возвращают значение ошибочного индекса и диапазон допустимых индексов.

class range

{int i;

int s;

public:

range(int I,int S):i(I),s(S){}

int get_index(){return i;}

void index_range(){cout<<"Допустимый диапазон:0 - "<<s<<endl;}

};

При ошибке создается объект range, содержащий уже два значения: ошибочный индекс и максимальное значение индекса.

char& string::operator[](int j)

{if((j<0)||(j>=size)) throw range(j,size); return p[j];}

Таким образом, поскольку исключение–это класс, он может содержать любые поля и методы.

5.3. Определение типа исключения

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

class string

{…

public:

class range{};

class error_size{};

string(int);

~string();

char& operator[](int);

};

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

string : : string(int s)

{if((s<0)||(s>max)) throw error_size();

p=new char[size=s];

}

или таким образом:

string : : string(int s)

{p=new char[size=s];

if(!p) throw error_size();

}

Тогда прикладная программа выглядит следующим образом:

void main()

{…

try

{

описание и выполнение каких-либо операций с объектами класса string

}

catch(string : : range){…}

catch(string : : error_size){…}

}

При наличии ошибки активизируется соответствующий обработчик исключений.

void f()

{…

try{…}

catch(string : : range)

{исправление ошибки и повторный вызов функции f();

}

catch(string : : error_size)

{выдача сообщений и завершение программы

exit(1);

}

}

Здесь записана часть функции, которая будет выполнена, если либо не было исключений, либо была достигнута закрывающая фигурная скобка исключения range. Функция f может перехватывать лишь некоторые исключения. Например, можно рассмотреть такие две функции f1 и f2, что f1 перехватывает только error_size, а f2 – только range. В этом случае после блока try первой функции записывается один блок catch(string : : error_size), а после блока try второй – один блок catch(string : : range).

Также можно в программе использовать два блока try, один из которых позволяет выявлять ошибки конструирования объекта, а второй – ошибки индекса.