Исключения в конструкторах

Оба числа отличны от нуля;

Оба числа неотрицательны;

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

Пример применения механизма исключений (из Подбельского) при определении функции определения наибольшего общего делителя (НОД) двух целых чисел (алгоритм Евклида):

· если x==y, то ответ найден, НОД = x;

· если x<y, то y заменяется значением y-x;

· если x>y, то x заменяется значением x-y;

· алгоритм применим при соблюдении условий

Этим ситуациям соответствуют два исключения. В первом случае исключением будет объект библиотечного класса string. Во втором случае, когда появляется нулевой параметр, в качестве исключения посылается значение второго, возможно ненулевого параметра, типа int.

#include <iostream>

#include <string>

using namespace std;

int GCD (int x, int y) {

if (x==0) throw y;

if (y==0) throw x;

if(x<0) throw string(“\nNegative parameter 1”)

if(y<0) throw string(“\nNegative parameter 2”)

while(x!=y) {

if(x>y) x=x-y;

else y=y-x;

}

return x;

}

int main() {

try{

cout<<”GCD(77,55) = ”<<GCD(77,55)<<endl;

cout<<”GCD(0,5) = ”<<GCD(0,5)<<endl;

cout<<”GCD(-7,4) = ”<<GCD(-7,4)<<endl;

}

catch(const string msg){

cout<<msg<<endl;

}

catch(const int ex){

cout<<” One parameter is ZERO!”;

cout<<” Another parameter equals “<<ex<<endl;

}

return 0;

}

Результат выполнения программы:

GCD(77,55)=11

One parameter is ZERO! Another parameter equals 5

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

В основной программе в блоке try три обращения к функции GCD(), причем, только первое не содержит ошибочных параметров.

Первый обработчик ловит исключение типа string, второй – типа int.

При втором вызове с нулевым параметром посылается исключение типа int, и после его обработки выполнение программы завершается, управление не передается в блок try.

Третий вызов функции вообще не выполняется.

В данном примере в качестве исключений использованы стандартные и библиотечные типы (int, string).

Намного удобнее в качестве исключения использовать объекты пользовательских классов.

Модифицируем пример, вводя специальный класс для исключений.

#include <iostream>

#include <string>

using namespace std;

struct DATA { //класс объектов - исключений

int n, m;

string s;

DATA (int x, int y, string str): //конструктор

n(x), m(y),s(str) { }

};

int GCD (int x, int y) {

if (x== 0 | | y ==0) throw DATA(x, y, ”ZERO!”);

if(x<0) throw DATA(x, y, “Negative parameter 1”)

if(y<0) throw DATA(x, y, “Negative parameter 2”)

while(x!=y) {

if(x>y) x=x-y;

else y=y-x;

}

return x;

}

int main() {

try{

cout<<”GCD(77,55) = ”<<GCD(77,55)<<endl;

cout<<”GCD(0,5) = ”<<GCD(0,5)<<endl;

cout<<”GCD(-7,4) = ”<<GCD(-7,4)<<endl;

}

catch(DATA d){

cerr<<d.s<<” x= “<<d.n<<”, y= “<<d.m<<endl;

}

return 0;

}

Результат выполнения программы:

GCD(77,55)=11

ZERO! x=0, y= 5

Последнее обращение GCD(-7,4) не выполнено.

Исключения формируются как объекты специального класса DATA, который определен как структура с общедоступными полями.

Объекты класса DATA формируются в одной функции, но доступны в другой функции. Это особое свойство исключений, они создаются как статические объекты в одном блоке, но доступны в другом.

Достоинством исключений является временной разрыв между разработкой функции, генерирующей исключение, и определением алгоритмов обработки исключения.

После обработки исключения нельзя вернуться в блок, откудо исключение было послано!

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

Так как обработчики исключений выполняются последовательно, то обработчик без параметров следует располагать в конце последовательности!

После него никакой обработки исключений уже не будет.

Стандартом введена новая форма генерации и обработки исключений в конструкторах классов.

Внешнее определение конструктора может иметь такой вид:

имя_класса::имя_класса (спецификация параметров)

try: список инициализаторов

{операторы тела конструктора}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: