Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кетков.doc
Скачиваний:
17
Добавлен:
27.09.2019
Размер:
2.22 Mб
Скачать

17.2. Исключения

Для обработки нештатных ситуаций в язык C++ внесены следующие служебные слова – try (попробуй, проверь), catch (перехвати) и throw (имитируй событие). В версии BC 3.1 эти средства еще не были задействованы, поэтому содержимое настоящего раздела распространяется на среду Borland C++ Builder.

Программный блок, в котором могут возникнуть нештатные события, заключается в фигурные скобки, перед которыми располагается служебное слово try:

try { контролируемый участок программы }

Если на контролируемом участке программы возникает та или иная особая ситуация, то для ее анализа надо предусмотреть одну или несколько ловушек, каждая из которых начинается со служебного слова catch:

catch(тип_события_1 значение_события_1) { блок обработки события_1 }

catch(тип_события_2 значение_события_2) { блок обработки события_2 }

.........................................................

Аргумент оператора catch можно рассматривать как специфический объект некоторого класса. Этот объект может быть создан как в результате аварийной ситуации, фиксируемой операционной системой, так и в результате выполнения программой оператора throw. Вторая возможность позволяет программе пользователя генерировать особые ситуации в случае выполнения условий, запланированных в работе алгоритма, и структурировать обработку возникающих событий в блоках catch.

Рассмотрим в качестве примера защищенную функцию fact(n), вычисляющую n!, которая возвращает значение типа double. По определению аргумент функции факториал не может быть отрицательным, а из диапазона представления вещественных данных типа double следует, что аргумент n не должен превосходить величины 1754, т.к. 1755! > 1e+308. Конечно, проверки аргумента на принадлежность допустимому интервалу можно было предусмотреть в теле функции, например, следующим образом:

double fact(int n)

{ if(0>n || n>1754)

{ cerr<<"fact: недопустимый аргумент"<<endl;

getch(); exit(1)

}

if(n==0)return 1;

else return n*fact(n-1);

}

Однако такая жесткая реакция на недопустимый аргумент всегда приведет к завершению работы приложения. А вдруг в распоряжении пользователя имеется возможность изменить схему алгоритма, и в ответ на возникшую ситуацию он захочет предпринять какие-то другие действия. Бóльшую гибкость в подобной ситуации может обеспечить следующая схема:

double fact(int n)

{ try

{ if(n<0) throw "fact: Argument < 0";

if(n>1754) throw "fact: Argument too big";

if(n==0)return 1;

else return n*fact(n-1);

}

catch(const char *s)

{ cerr<<s<<endl; //вывод сообщения об ошибке

return -1; //возврат несуществующего значения функции

}

}

В приведенном примере в случае выхода аргумента за пределы области определения срабатывает один из операторов throw, который генерирует объект типа символьная строка и прерывает работу контролируемого блока try (напоминает выход из цикла по оператору break). Ловушка catch настроена на перехват исключений типа символьная строка, об этом свидетельствует тип ее аргумента. В процессе обработки возникшего события блок catch выводит полученное сообщение и возвращает несуществующее значение функции. По такому результату вызывающая программа может сообразить, что необходимо предпринять для продолжения работы. Если аргумент функции fact оказался допустимым, то после удачного выполнения блока try фрагмент программы-ловушки обходится.

Следует заметить, что механизм обработки исключений еще не попал в стандарт языка C++, поэтому разные системы программирования проводят обработку таких событий по-разному. Система BCB, обнаружив оператор throw, сначала выдает общее предупреждение о происшедшем событии:

Project ... raised exception class char * with message 'Exception Object Address: ...'

Process Stopped. Use Step or Run to continue.

После этого нажатие клавиши F9 (команда Run) или F8 (команда Step) передает управление блоку catch, который выдает сообщение, сгенерированное соответствующим оператором throw. В автоматическом режиме функция fact выдаст несуществующее значение факториала и программа продолжит свою работу:

void main()

{ int x=-5;

double z=fact(x);

cout<<"fact("<<x<<")="<<z<<endl;

getch();

}

//=== Результат работы ===

fact: Argument < 0

fact(-5)=-1

Система Visual C++ в такой ситуации не выдает системное предупреждение и не останавливает процесс – происходит просто автоматическая передача управления блоку catch.

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

double fact(int n)

{ try

{ if(n<0) throw EInvalidArgument("fact: Argument < 0");

if(n>1754) throw EInvalidArgument("fact: Argument too big");

if(n==0)return 1;

else return n*fact(n-1);

}

catch(EInvalidArgument &s)

{ cerr<<s.Message.c_str()<<endl; //вывод сообщения об ошибке

return -1; //возврат несуществующего значения функции

}

}

Для правильной работы такой функции нам понадобится подключение заголовочного файла math.hpp, в котором находится описание класса EInvalidArgument. В модифицированном варианте функции оператор throw использует конструктор этого класса для генерации ссылки на соответствующий объект. После обработки события в блоке catch созданный объект будет автоматически уничтожен. Обратите внимание на то, что все объекты класса Exception (и порожденных классов тоже) обладают свойством Message, значение которого представлено строкой типа AnsiString. Именно поэтому при выводе сообщения его приходится преобразовывать в обычную строку с помощью функции c_str.

Использование классов типа Exception существенно расширяет многообразие нестандартных ситуаций, которое может предусмотреть программа пользователя. Если бы для индикации событий мы использовали только переменные базовых типов, то количество различных ситуаций не превышало бы десятка (char*, unsigned char*, short int, unsigned short int, ...).

Если в защищенном блоке может возникнуть несколько особых событий, которые связаны с разными объектами одного типа, то после блока try можно предусмотреть несколько обработчиков исключительных ситуаций. Последовательность их размещения может повлиять на правильность реакции на происшедшее событие. Дело в том, что сначала управление попробует получить блок catch, расположенный сразу после блока try. Если блок catch ориентирован на обработку однотипного события с другим значением, то при выходе из блока catch полученный объект-исключение будет уничтожен. И тогда следующий блок catch, который мог бы справиться с возникшей ситуацией, уже не сработает. Поэтому первый блок catch, получив управление и обнаружив, что событие адресовано не ему, должен позаботиться о сохранении объекта для следующего обработчика. Для этого в конце первого блока catch должен находиться оператор throw().

В программах, связанных с обработкой исключений, можно встретить ловушку catch с аргументом в виде трех точек (catch(...)). Такая ловушка перехватывает исключения любого типа.

Литература по С/С++

  1. Аксенкин М.А., Целобенок О.Н. Язык С. Минск: Унiверсiтэцкае, 1995. – 302 с

  2. Александреску А. Современное программирование на С++. Серия C++ InDepth. т.3, М.: Вильямс, 2002. – 336 с

  3. Аммерааль Л. STL для программистов на С++. М.: ДМК, 1999. – 240 с

  4. Арнуш К. Borland C++ 5. Освой самостоятельно. М.: БИНОМ

  5. Архангельский А.Я. Библиотека С++ Builder 5. М.: БИНОМ, 2000. ч.1 60 управляющих компонент – 256 с, ч.2 70 компонентов ввода/вывода информации – 288 с

  6. Бабэ Б. Просто и ясно о Borland C++. М.: БИНОМ, 1994. – 400 с

  7. Бадд Т. Объектно-ориентированное программирование в действии. СПб.: Питер, 1997. – 464 с

  8. Баркакатти Н. Программирование игр для Windows на Borland C++. М.: БИНОМ, 1994. – 512 c

  9. Белецкий Я. Энциклопедия языка Си. М.: Мир, 1992. – 685 с

  10. Белецкий Я. Турбо С++: Новая разработка. М.: Машиностроение, 1994. – 400 с

  11. Березин Б.И., Березин С.Б. Начальный курс С и С++. М.: Диалог-МИФИ, 1988. – 288 с

  12. Берри Р., Микинз Б. Язык С: введение для программистов. М.: Финансы и статистика, 1988. – 191 с

  13. Болски М.И. Справочник. Язык программирования Си. М.: Радио и связь, 1986. – 96 с

  14. Бочков С.О., Субботин Д.М. Язык программирования Си для персонального компьютера. М: Радио и связь, 1990. – 384 с

  15. Бошкин А.В., Дубнер П.Н. Работа в Турбо Си. М.: НИВФ ЮКИС, СП "Ланит", 1991. – 183 с

  16. Браунси К. Основные концепции структур данных и реализация в С++. М.: Вильямс, 2002. – 320 с

  17. Буч Г. Объектно-ориентированный анализ и проектирование с приложениями на С++. 2-е изд. М.: БИНОМ, СПб: Невский диалект, 1988. – 560 с

  18. Буч Г. Объектно-ориентированный анализ и проектирование с примерами применения. М.: Конкорд, 1992. – 519 с

  19. Вайнер Р., Пинсон Л. С++ изнутри. Киев: ДиаСофт, 1993. – 304 с

  20. Власов С.Е. Разработка программ в интегрированной среде Турбо Си. Н.Новгород: НКЦП, 1992. – 111 с

  21. Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. Приемы объектно-ориентированного проектирования. паттерны проектирования. Серия: Библиотека программиста. СПб.: Питер, 2001. – 368 с

  22. Голуб А.И. С &С++. Правила программирования. М.: БИНОМ, 1996. – 272 с

  23. Дансмур М., Дейвис Г. Операционная система Unix и программирование на языке Си. М.: Радио и связь, 1989. – 192 с

  24. Дейтел П. Дж., Дейтел Х.М. Как программировать на С++. Введение в объектно-ориентированное проектирование с использованием UML. М.: БИНОМ, 2002. – 1152 с

  25. Джамса К. 1001 совет по С/С++. Настольная книга программиста. М.: Март, БИНОМ, Универсал, 1997. – 784 с

  26. Джехани Н. Программирование на языке Си. М.: Радио и связь, 1988. – 270 с

  27. Джонс Р., Стюарт Я. Программируем на Си. М.: изд. объединение ЮНИТИ, Компьютер, 1994. – 236 с

  28. Дьюхарст С., Старк К. Программирование на С++. Киев: ДиаСофт, 1993. – 272 с

  29. Жешке Р. Толковый словарь стандарта языка Си. СПб.: Питер, 1994. 221 с

  30. Кардышев С.В., Капкин А.М. Интерфейс программиста Турбо Си. М.: Радио и связь, 1992. – 192 с

  31. Каррано Ф.М., Причард Дж. Дж. Абстракция данных и решение задач на С++ Стены и зеркала. М.: Вильямс, 2003. – 848 с

  32. Касаткин А.И., Вальвачев А.Н. Профессиональное программирование на языке Си. От Turbo C к Borland C++. Справочное пособие. Минск: Вышейшая школа, 1992. – 240 с

  33. Кениг Б., Му Б.Э. Эффективное программирование на С++. Серия C++ InDepth, М.: Вильямс, 2002. – 384 с

  34. Керниган Б.В., Пайк Р. Практика программирования. СПб.: Невский диалект, 2001. – 381 с

  35. Керниган Б., Ритчи Д., Фьюзер А. Язык программирования Си. Задачи по языку Си. М.: Финансы и статистика, 1985. – 279 с

  36. Керниган Б., Ритчи Д. Язык программирования Си. 3-е изд., СПб.: Невский диалект, 2001. – 352 с

  37. Кетков Ю.Л., Кетков А.Ю. Практика программирования: Бейсик, Си, Паскаль. СПб.: БХВ-Петербург, 2001. – 480 с

  38. Кетков Ю.Л., Кетков А.Ю. Практика программирования: Visual Basic, C++ Builder, Delphi. СПб.: БХВ-Петербург, 2002. – 464 с

  39. Кимел П. и др. Borland C++ 5. СПб.: БХВ-Петербург, 2000. – 976 с

  40. Котлинская Г.П., Галиновский О.И. Программирование на языке Си. Справочное пособие. Минск: Высш. школа, 1991. – 156 с

  41. Круглински Д., Уингоу С., Шеферд Дж. Программирование на Microsoft Visual C++ 6.0 для профессионалов. СПб.: Питер, М.: Русская редакция, 2001. – 864 с

  42. Лаптев В. С++. Экспресс-курс. СПб.: БХВ-Петербург, 2004. – 512 с

  43. Левкин Г.Н., Левкина В.Е. Демо Турбо Си: 98 тем для начинающих программистов. Витебск: МП "ПРОК", 1992. – 199 с

  44. Линдли К. Практическая обработка изображений на языке Си. М.: Мир, 1996. – 512 с

  45. Липпман С.Б. С++ для начинающих. М.: Унитех, Рязань: Гэлион, 1993. т.1 – 304 с, т.2 – 345 с

  46. Липпман С.Б., Лажойе Ж. Язык программирование С++. Вводный курс, 3-е изд. СПб: Невский проспект, М.: ДМК Пресс, 2001. – 1104 с

  47. Липпман С.Б. Основы программирования на С++. Серия C++ InDepth, М.: Вильямс, 2002. – 256 с

  48. Луис С. Borland C++ 5. Справочник. М.: БИНОМ, 1997. – 560 с

  49. Луис Д. С и С++. Справочник. М.: Восточная книжная компания, 1997. – 592 с

  50. Лукас П. С++ под рукой. Киев: ДиаСофт, 1993. – 176 с

  51. Маргулев А.И. Язык Си для PC. Учебное пособие. М.: Агар, 1997. – 182 с

  52. Марченко А.Л. С++. Бархатный путь. М.: Горячая линия – Телеком, 1999. – 400 с

  53. Мейерс С. Эффективное использование С++. 50 рекомендаций по улучшению наших программ и проектов. Серия Для программистов. М.: ДМК Пресс, 2000. – 240 с

  54. Мейерс С. Наиболее эффективное использование С++. 35 новых рекомендаций по улучшению наших программ и проектов. Серия: Для программистов. М.: ДМК Пресс, 2000. – 304 с

  55. Мейерс С. Эффективное использование STL. Библиотека программиста. СПб.: Питер, 2002. – 224 с

  56. Мешков А.В., Тихомиров Ю.В. Visual C++ и MFC. СПб.: БХВ-Петербург, 2000. – 1040 с

  57. Москвин П.В. Азбука STL. М.: Горячая линия – Телеком, 2003. – 262 с

  58. Намиот Д.Е. Язык программирования TURBO C++. Учебное пособие. М.: МГУ, 1991. – 121 с

  59. Нейбауэр А. Моя первая программа на С/С++. СПб.: Питер, 1996. – 364 с

  60. Неформальное введение в С++ и Turbo Vision. СПб.: Галерея "ПЕТРОПОЛЬ", 1992. – 384 с

  61. Нортон П., Йао П. Программирование на Borland C в среде Windows. 1993. ч.1 – 320 с, ч.2 – 320 с

  62. Олафсен Ю., Скрайбер К., Уайт К.Д. и др. MFC и Visual C++ 6. Энциклопедия программиста. СПб.: ДиаСофтЮП, 2003. – 992 с

  63. От Си к Си++./ Козелл Е.И. и др. М.: Финансы и статистика, 1993. – 272 с.

  64. Павловская Т.А. С/С++. Программирование на языке высокого уровня. СПб.: Питер, 2002. – 464 с

  65. Павловская Т.А., Щупак Ю.А. С/С++. Структурное программирование. Практикум. СПб.: Питер, 2002. – 240 с

  66. Паппас К., Мюррей У. Си/Си++: руководство программиста. М: СК Пресс. 1997. кн. 1 – 492 с, кн.2 – 493 с

  67. Подбельский В.В. Язык С++. М.: Финансы и статистика, 5-е изд, 2002. – 560 с

  68. Подбельский В.В., Фомин С.В. Практикум программирования на языке Си: Учебное пособие. 2-е изд. М.: Финансы и статистика, 2002. – 600 с

  69. Пол И. Объектно-ориентированное программирование с использованием С++. Киев: DiaSoft Ltd, 1995. – 480 с

  70. Прата С. Язык программирования С. Лекции и упражнения. Киев: ДиаСофт, 2000. – 432 с

  71. Прата С. Язык программирования С++. Лекции и упражнения. Учебник. Киев: ДиаСофт, 2001. – 656 с

  72. Прокофьев Б.П., Сухарев Н.Н., Хромов Ю.Е. Графические средства Turbo C и Turbo C++. М.: Финансы и статистика, СП "Ланит", 1992. – 160 с

  73. Романов В.Ю. Программирование на языке С++. Практический подход. М.: Компьютер, 1993. – 160 с

  74. Романов Е.Л. Язык Си++ в задачах, вопросах и ответах. Серия: Учебники НГТУ. Новосибирск, НГТУ, 2003. – 428 с

  75. Романовская Л.М., Русс Т.В., Свитковский С.Г. Программирование в среде Си для ПЭВМ ЕС. М.: Финансы и статистика, 1991. – 352 с

  76. Россохин Д.Н. От Си к Си++. М.: Эдель, 1993. – 128 с

  77. Саттер Г. Решение сложных задач на С++. Серия C++ InDepth, М.: Вильямс, 2002. – 400 с

  78. Сван Т. Программирование для Windows в Borland C++. М.: БИНОМ, 1995. – 480 с

  79. Сван Т. Освоение Borland C++ 4.5. Практический курс. Киев: Диалектика, 1996. – 544 с

  80. Сван Т. Освоение Borland C++ 4.5. Энциклопедия фуекций. Киев: Диалектика, 1996. – 320 с

  81. Секунов Н. Самоучитель С#. СПБ.: БХВ-Петербург. .... – 576 с

  82. Секунов Н. Visual C++ 6. СПБ.: БХВ-Петербург. .... – 960 с

  83. Скляров В.А. Программирование на языках Си и Си++. Минск: Высш. школа, 1996. – 240 с

  84. Собоцинский В.В. Практический курс на Turbo C++. Основы объектно-ориентированного программирование. М.: Свет, 1993. – 236 с

  85. Страуструп Б. Язык программирования С++. М.: Радио и связь, 1991. – 352 с

  86. Страуструп Б. Язык программирования С++. Второе издание. Киев: ДиаСофт, 1993. ч.1 – 264 с, ч.2 – 296 с

  87. Страуструп Б. Язык программирования С++. М.:БИНОМ, СПб.: Невский диалект, 2001. – 1099 с

  88. Страуструп Б. Дизайн и эволюция С++. Серия: Для программистов. М.: ДМК Пресс, 2000. – 448 с

  89. Сэджвик Р. Фундаментальные алгоритмы на С++. Анализ. Структуры данных. Сортировка. Поиск. К.: ДиаСофт, 2001. – 688 с.

  90. Сэджвик Р. Фундаментальные алгоритмы на С++. Алгоритмы на графах. К.: ДиаСофт, 2002. – 496 с.

  91. Сэтвич У. С++ в примерах. М.: ЭКОМ, 1997. – 734 с

  92. Тарасов В.Л. Упражнения по языку программирования Си: Учебное пособие. Н.Новгород: изд. ННГУ, 1996. – 178 с

  93. Тондо К., Гимпел С. Язык Си. Книга ответов. М.: Финансы и статистика, 1994

  94. Трой Д. Программирование на языке Си для персонального компьютера IBM PC. М.: Радио и связь, 1991. – 432 с

  95. Уинер Р. Язык ТУРБО СИ. М.: Мир, 1991. – 384 с

  96. Уолнэм К. Объектно-ориентированное программирование. Borland C++. Минск: Попурри, 1997. – 640 с

  97. Уэйт М., Микинз Б., Мартин Д. Язык Си. М.: Мир, 1988. – 512 с

  98. Уэйт М., Прата С., Мартин Д. Язык Си. Руководство для начинающих. М.: Мир, 1988. – 512 с

  99. Фейсон Т. Объектно-ориентированное программирование на Borland C 4.5. Киев: Диалектика, 1996. – 544 с

  100. Фридман А.Л., Основы объектно-ориентированного программирования на языке С++. М.: Горячая линия Телеком, Радио и связь, 1999. – 208 с

  101. Фридман А., Кландер Л., Михаэлис М., Шилдт Х. С/С++. Архив программ. М.: БИНОМ, 2001. – 640 с

  102. Хаймен М. Borland C++ для чайников. Киев: ICE, Диалектика, 1995. – 416 с

  103. Халперн П. Стандартная библиотека С++ на примерах. М.: Вильямс, 2001. – 336 с

  104. Хенкеманс Д., Ли М. Программирование на С++. СПб.: Символ-Плюс, 2002. – 416 с

  105. Холзнер С. Visual C++ 6: Учебный курс. СПб.: Питер, 1999. – 576 с

  106. Холингвэрт Д., Баттерфилд Д., Сворт Б., Олсон Д. и др. C++ Builder. Руководство разработчика. В 2-х томах. М., Киев, СПб.: изд. дом Вильямс, 2001. т.1 Основы – 880 с. т.2 Сложные вопросы программирования – 832 с

  107. Хэзфилд Р., Кирби Л. и др. Искусство программирования на С. Фундаментальные алгоритмы, структуры данных и примеры приложений. Энциклопедия программиста. К.: ДиаСофт, 2001. – 736 с.

  108. Хэнкок Л., Кригер М. Введение в программирование на языке Си. М.: Радио и связь, 1986. – 192 с

  109. Цимбал А.А., Майоров А.Г., Козодоев М.А. Turbo C++: Язык и его применение. М.: Джен Ай Лтд, 1993. – 512 с

  110. Чан Т. Системное программирование на С++ для UNIX. Киев: BHV, 1997. – 592 с

  111. Шилдт Г. Программирование на C и С++ для Windows 95. Киев: BHV, 1996. – 400 с

  112. Шилдт Г. MFC: Основы программирования. Киев: BHV, 1997. – 556 с

  113. Шилдт Г. Самоучитель С++. СПб.: БХВ-Петербург, 1997. – 512 с

  114. Шилдт Г. Справочник программиста по С/С++. М.: изд. дом Вильямс, 2001. – 448 с

  115. Шилдт Г. Теория и практика С++. СПб.: БХВ-Петербург, 2000. – 416 с

  116. Элджер Дж. С++ : библиотека прогаммиста. СПб.: Питер, 1999. – 320 с

  117. Эллис М., Строуструп Б. Справочное руководство по языку программирования С++ с комментариями. Проект стандарта ANSI. М.: Мир, 1992. – 445 с

  118. Янг М. Программирование графики в Windows 95: Векторная графика на языке С++. М.: БИНОМ, 1997. – 366 с

  119. Turbo C++. Руководство пользователя. М.: СП ИНТЕРКВАДРО, 1991. – 298 с, Руководство программиста – 394 с, Справочник по библиотеке – 568 с

174