Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Содержание сайт... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Invision Power ... 65308
Организация зап... 63966
Модуль Forms 60864
Создание отчето... 60740
ТЕХНОЛОГИИ ДОСТ... 57065
Создание потоко... 56443
Пример работы с... 54322
Имитационное мо... 52517
Реклама
Сейчас на сайте
Гостей: 12
На сайте нет зарегистрированных пользователей

Пользователей: 13,065
новичок: railval
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование вычислительного центра на GPSS + Отчет + Блок схема
Моделирование автовокзала + Отчет + Блок схема
Моделирование интернет кафе на GPSS + Отчет

Реклама



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

ПОДПИСЫВАЙСЯ на канал о программировании
Применение исключений
Прежде чем переписывать конструкторы и методы разработанных ранее классов с использованием механизма обработки исключений, давайте обратимся к этому механизму для проверки параметров в обычной функции. Пусть нам требуется написать функцию, вычисляющую высоту, опущенную на одну из сторон. Параметрами являются три стороны треугольника, а вычислять нужно высоту, опущенную на сторону, указанную первой. Если параметры-стороны заданы в порядке а, Ь, с, то вычислять надо высоту, опущенную на сторону а. Как известно, высота, опущенная на сторону а, вычисляется по формуле
К ->JP(P а)(р Ь)(р с), а



где р = (а + Ъ + с)/2 — полупериметр треугольника. Квадратный корень представляет собой формулу Герона для вычисления площади треугольника. Таким образом, нам надо проверить, что:
• ни один из параметров (сторона треугольника) не меньше нуля и не равен нулю;
• выполняются неравенства треугольника для любых сочетаний сторон.
Если эти условия не выполняются, то функция должна генерировать исключение, которое является сообщением об ошибке. Вывод этого сообщения должен быть выполнен в блоке catch. Используем тип string, а передавать объект-исключение в секцию-ловушку будем по константной ссылке. Нам требуется решить, кто будет обрабатывать исключение: та же функция, где ситуация возникла, или программа-клиент. Рассмотрим сначала первый вариант (листинг 7.1).
Листинг 7.1. Функция вычисления высоты треугольника с обработкой исключений
double Ha(double a, double b, double с)
{ try { // контролируемый блок
if ((a>0)&&(b>0)&&(c>0)) // если параметры правильные
{ if ((a+b>c)&&(a+c>b)&&(b+c>a)) // если треугольник
{ double р = (a+b+c)/2; // вычисляем высоту
return 2*sqrt(p*(p-a)*(p-b)*(p-c))/a:
}
}
else throw "Неправильный параметр!"; // генерация исключения
} // конец try-блока
catch(const string &s) // обработка исключения
{ cout << s << endl; } y
}
Уже по тексту функции видно, что механизм обработки исключения в данном варианте является «лишним» — можно просто выводить сообщение. Использование исключений в функции существенно усложнило текст. Тем не менее все-таки проверим функцию с помощью простейшей тестовой программы:
int main()
{ cout <<На(3,4,5)<< endl; // выполняется правильно
cout <<На(1,2,3)<< endl; // ничего не выводится!
return 0;
}



Первый оператор выполняется нормально, так как параметры заданы правильные — это стороны прямоугольного треугольника. А вот со вторым оператором возникли проблемы — программа завершается аварийно, но на экран не выводится никаких сообщений, ради которых мы, собственно, и «городили огород» с исключениями! Такое впечатление, что секция-ловушка просто не выполняется.
Так оно и есть на самом деле! Причина состоит в том, что тип генерируемого объекта-исключения не соответствует типу, заявленному в секции-ловушке catch. Операторы throw генерируют объект, тип которого const char *, а в заголовке секции-ловушки заявлен const string&. Преобразования типов по умолчанию, как отмечалось ранее, не выполняются. Если бы преобразования были разрешены, невозможно было бы перехватывать исключение конкретного типа. Поэтому перепишем заголовок блока catch с правильным типом параметра:
catch (const char *s)
Программа заработала, однако на экране появляются «лишние» сообщения:
Не треугольник! -l.#IND



Последнее сообщение появляется из-за того, что мы не возвращаем никакого значения в аварийных случаях. Между тем функция, выполнив блок catch, выполняет операторы после него, а у нас там ничего нет! Первое решение — поставить в функцию после, секции-ловушки оператор
return 0;



Теперь наша тестовая программа выводит на экран два числа: 4 и 0. Однако использование механизма обработки исключений в таком варианте выглядит абсолютно нецелесообразным — гораздо проще сделать все то же самое с помощью обычных операторов i f. Поэтому реализуем другой вариант обработки: функция будет только генерировать исключение, а обрабатывать его будет программа-клиент, в данном случае — наша тестовая программа. Текст функции с программой-клиентом представлен в листинге 7.2.
Листинг 7.2. Функция вычисления высоты треугольника с генерацией исключений
double Ha(double a, double b, double с)
{ if ((a>0)&&(b>0)&&(c>0)) // если параметры правильные
{ if ((a+b>c)&&(a+c>b)&&(b+c>a)) // если треугольник
{ double р = (a+b+c)/2: // вычисление высоты
return 2*sqrt(p*(p-a)*(p-b)*(p-c))/a:
}
else throw "He треугольник!": // генерация исключения
}
else throw "Неправильный параметр!": // генерация исключения
}
int main()
{ try { // контролируемый блок
cout <<На(3,4,5)<< endl: // нормальное вычисление
cout <<На(1,2,3)<< endl: // генерирует исключение
cout <<На(1,0,3)<< endl: // не выполняется!
}
catch(const char *s) // обработка исключения
{ cout << s << endl: } return 0:
}



Обратите внимание на то, что в функции не выполняется возврат «аварийного» значения 0: в данном случае этого не требуется, так как оператор генерации исключения осуществляет выход из функции. При этом выполняется «раскрутка» стека: вызываются все необходимые деструкторы для уничтожения локальных объектов. Поэтому вернуться в функцию после генерации исключения невозможно — разве что заново ее вызвать.
Первый оператор вывода срабатывает нормально. Во время выполнения второго возникает исключение, и управление передается в секцию-ловушку. При этом пропускается третий оператор вывода. Причем мы не можем «вернуться» к его выполнению после выполнения секции-ловушки, даже если пометим его и добавим оператор goto: по стандарту оператор goto не может использоваться для перехода внутрь контролируемого блока. Но можно передать управление на начало блока try и выполнить весь контролируемый блок сначала. Правда, в данном случае — без корректировки параметров во втором вызове — это не изменит поведения программы: третий оператор все равно не будет работать.
Наша функция не имеет спецификации исключений. Наличие спецификации в заголовке никак не изменяет поведения программы, например:
double Ha(double a, double b, double с) throw(const char *)



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

Однако в Visual C++.NET 2003 задание спецификации с другим типом исключения на видимое поведение программы никак не влияет, например:
double Ha(double a, double b, double с) throw(string)



To же самое происходит при полном запрете исключений:
double Ha(double a, double b, double с) throw()



Главное, чтобы генерируемое исключение было где-нибудь перехвачено.
Опубликовал Kest November 11 2013 03:50:47 · 0 Комментариев · 2237 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Java Server Pages...
Искусство програм...
GPSS World Studen...
DragMe [Исходник ...
около 291 статьи ...
Добавление басса ...
XPATComponents
Borland C++Builde...
Создание Web-сайт...
Web Регистрация
Книга по Delphi (...
Песочные часы
CodeGear RAD Stud...
Профессиональное ...
ComboBox97
index.php + мод ...
Быстрое создание ...
Socoban
DemoEdit [Исходни...
Report

Топ загрузок
Приложение Клие... 100376
Delphi 7 Enterp... 83122
Converter AMR<-... 20046
Borland C++Buil... 11183
GPSS World Stud... 10948
Borland Delphi ... 8130
Turbo Pascal fo... 6973
Visual Studio 2... 4963
Калькулятор [Ис... 4373
FreeSMS v1.3.1 3510
Случайные статьи
Вывод текста в гра...
Калгари (штат Альб...
STORAGE (ПАМЯТЬ)
Назначение класса ...
Процедура GetFillP...
Label not within c...
Компоновка данных ...
Как узнать свой снилс
Средства отладки -...
Третий пункт
Содержание
Переустановка пров...
политику издания, ...
Кошачий туалет зак...
Методы класса TStr...
Время жизни сервера
Invalid drive number
String length mism...
Соединение по треб...
Пример программиро...
Сортировка
Объект DataView, с...
PREEMPT (ПРЕРВАТЬ)
Группа блоков созд...
Сохранение состоян...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?