ЗАМЕЧАНИЕ
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 новые значения. Далее в этой главе я объясню, как использовать исключительные ситуации в этом случае, но сначала вы должны узнать об альтернативных формах объявления функций, возбуждающих исключительные ситуации.