ЗАМЕЧАНИЕ

Else

Double Power(double b, double e)

{

if (b > 0.0) return Pow(b, e);

if (b < 0.0) {

double ipart;

double fpart = modf(e, &ipart);

//целая часть в &ipart, дробная - возвращается

if (fpart == 0) {

if (fmod(ipart, 2) != 0) // Т.о., ipart - нечетное число

return -Pow(-b, e);

return Pow(-b, e);

} else

throw Error(b, e); //

} else {

if (e == 0.0) return 1.0;

if (e < 1.0) throw Error(b, e); //попытка возвести

// отрицательное число дробную степень

return 0.0; }

throw Error(); // В этом месте будет предупреждение

}

// Отображение значений, вызвавших исключительную ситуацию

Void Error: :Report()

{ cout « "Domain error:"

« " base:" « b

<< " exponent:" << e

« endl;

}

В EXCEPT реализуется функция PowerO, способная возвести любое действительное число в любую действительную степень. Конечно, два условия исключительной ситуации заставляют функцию возбуждать исключительную ситуацию.

• Возведение отрицательного числа в дробную степень.

• Возведение нуля в отрицательную степень.

Для обработки подобных ситуаций наилучшим образом подходят исключительные ситуации. Имеются та! же следующие альтернативы — прервать выполнение программы (плохо), возвратить специальное значение (не подходит) или установить глобальный флаг ошибки (плохой стиль программирования).

Вместо применения этих относительно неудачных решений, функция Power возбуждает исключите льну] ситуацию, представленную объектом класса Error. Например, при попытке возвести отрицательное число дробную степень функция Power выполняет следующий оператор, создающий объект класса Error, инициализированный значениями b и е:

throw Error(b, e);

Вернемся к функции main(). Функция Power вызывается внутри блока try, часть которого приведем еще раз

try {

double ba.se, exponent, result

// ... запрашиваются основание и показатель степени

result = Power(base, exponent);

cout « "result == " << result « endl;

Если функция Power возбуждает исключительную ситуацию, присваивание переменной result и следующий оператор вывода пропускаются, а блок try немедленно завершается. Оператор catch следует сразу же за блоком try:

catch (Error& e) {

e.Report();

return -1;

}

return 0;

 

Если функция Power возбуждает исключительную ситуацию, объект е класса Error перехватывается по ссылке. В операторе catch вызывается функция-член Report класса Error для объекта исключительной ситуа­ции е, отображающая значения, приведшие к ненормальному завершению функции Power.

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

Итак, программа осуществляет полный контроль над исключительными ситуациями. Пример заканчивает работу с кодом завершения, если были ошибки, или 0, если ошибок не было. Это обычная практика для программ, хотя операционные системы DOS и Windows игнорируют возвращаемые программами значения.

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