89785

Исключения С++

Лекция

Информатика, кибернетика и программирование

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

Русский

2015-05-13

132.88 KB

4 чел.

Исключения С++

Содержание

Исключительные ситуации и их обработка

  •   стандартные библиотеки assert и  signal
  •   исключения в С++
  •   генерация исключений throw
  •   контрольный блок try
  •   функции-обработки исключений catch
  •   стандартные функции-обработки исключений
  •   стандартные исключения при работе с динамической памятью
  •   стандартные исключения класса exception

Исключительные ситуации и их обработка

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

Для предотвращения такого прерывания в С++ используются специальные приемы программирования.

Стандартная библиотека ASSERT.H

Стандартная библиотека ASSERT.H предоставляет макропроверки выражений:

assert(выражение);

Если результат выраженияложь, то выполнение программы прерывается с выводом диагностического сообщения.

Проверка не выполняется если определено макро NDEBUG.

Стандартная библиотека SIGNAL.H

Стандартная библиотека SIGNAL.H предоставляет механизм для простой обработки определяемых системой исключений:

#define SIGINT 2 /*сигнал прерывания*/

#define SIGFPE 8 /* исключение с плавающей точкой*/

#define SIGABRT 22 /*сигнал аварийного завершения*/

Такие исключения являются асинхронными и не выводят никаких сообщений.

Прототип функции raise() используют для генерации явного исключения:

raise(SIGFPE);//возбужден сигнал исключения с плавающей точкой

Подобные исключения могут обрабатываться и с помощью функции signal():

//вызов my_abrt()

signal(SIGABRT,my_abrt());

//действовать по умолчанию

signal(SIGABRT,SIG_DFL);

//игнорировать SIGFPE

signal(SIGFPE,SIG_IGN);

Пример#27. Использование SIGNAL.H

#include <signal.h>

#include <time.h>

#include <iostream.h>

#include <stdlib.h> //для exit(0)

//обработчик ИС SIGINT

void cntrl_c_handler(int sig);

inline double clk_psec()

{return static_cast<double>(clock())/CLOCKS_PER_SEC;}

int main()

{ int i=0, j;

cout<<“Считаем до J миллионов, введите j:”; cin>>j;

 j*=1000000;

 signal(SIGINT, cntrl_c_handler);

cout<<clk_psec()<<“ начальное время\n”;

 while (1){ ++i; if (i>j){

 cout<<clk_psec()<<“ конец цикла\n”;

 cout<<“ цикл исполнен ”<<j/1000000 <<“ миллионов раз”<<endl;

raise(SIGINT);//неявный вызов функции //обработчика ИС SIGINT

cout<<“\nвведите j:cin>>j;

j*=1000000; i=0;

cout<<clk_psec()<<“ начало цикла\n”;

}

}

}

//определение функции обработчика ИС SIGINT

void cntrl_c_handler(int sig)

{ char c;

 cout<<“прерывание”;

 cout<<“Введите Д для продолжения:”; cin>>c;

 if (c==‘Д’)

 signal (SIGINT, cntrl_c_handler);

else exit(0);

}

Исключения С++

Для реализации механизма обработки синхронных ИС введены следующие ключевые слова:

  •  try (контролировать)
  •  catch (ловить, перехватывать)
  •  throw (генерировать, порождать, бросать, посылать, формировать)

Генерация исключений

Конструкция вида:

throw выражение;

возбуждает исключение и передает обработку ИС в блок catch, которая и обрабатывает ее.

Конструкция без аргумента:

throw;

может использоваться внутри catch для перезапуска текущего исключения.

Генерация исключений

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

Выражение отлавливается catch, который может использовать его значение:

int i;

throw i;

catch (int n) {cerr<<n<<endl;}

Контрольные блоки

С помощью блока:

try

{операторы_контролируемого_блока}

список_обработчиков_catch

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

Обработчики

Обработчикэто функция с одним параметром, не возвращающая никакого значения:

  1.  обработчик использует значение исключения

catch {тип_исключения имя} {операторы}

  1.  обработчик не использует значение исключения. 

catch {тип_исключения} {операторы}

  1.  обработчик реагирует на любое исключение

catch {…} {операторы}

Пример #28. Использование механизма исключения в С++

#include <iostream.h>

//функция, генерирующая исключение

void compare(int k)

{ if (k%2 != 0) throw k;

else throweven”;

}

//Функция с контролем и обработкой исключений

void GG(int j)

{ try

 { try {compare(j);}

 catch (int n)

  {cout<<“\nOdd”;

//генерация исключения во внешнем блоке try

  throw;}

 catch (const char*)

  {cout<<“\nEven”;}

 }

 catch (int i){cout<<“\nResult=”<<I;}

}

//Главная часть 

int main(){GG(4); GG(7); return 0;}

Результат работы программы:

Even

Odd

Result=7

Системные функции обработки исключений

К ним относятся:

  •  terminate() –когда нет ни одного обработчика
  •  unexpected() –когда исключение отсутствует в списке
  •  abort() –вызывается по умолчанию
  •  exit()вызывается для прерывания программы

Их поведение состоит в вызове функции terminate(), которую можно переопределить, используя функцию:

set_terminate()

Вызов функции unexpected() можно переопределить с помощью функции:

set_unexpected()

Пример #29. Замена функции terminate()

#include <stdlib.h>// abort()

#include <except.h>

#include <iostream.h>

//указатель на предыдущую функцию

 void (*old_terminate)();

//новая функция обработки //неопознанного исключения

 void new_terminate()

{cout<<“\nNew”; abort();}

int main()

{//установка своей функции обработки

 old_terminate= set_terminate  (new_terminate);

//генерация исключения вне //контролирующего блока try

 throw(25);

return 0;

}

Стандартные исключения при работе с динамической памятью

Исключение типа xalloc (except.h) запускается, если оператору new не удается выделить место в свободной памяти, при этом вызывается функция, адресуемая указателем _new_handler().

Функция (new.h)

set_new_handler(my_handler) ;

позволяет назначить свою функцию my_handler для обработки такого исключения.

Пример #30. При выделении динамической памяти

#include <iostream.h>

#include <new.h> //set_new_handler()

#include <stdlib.h>//abort()

void new_new_handler()

{cerr<<“Ошибка при выделении памяти!”; abort(); }

int main()

{set_new_handler(new_new_handler);

for (int i=1;i<=1000; i++)

{cout<<n;

new char[614400]; //пытаемся выделить 60Кб

 cout<<“: Успех!”<<endl;}

 return 0;

}

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

  1.  Из интегрированной среды Borland C++ 3.1 
  •  ошибка при n=1
  1.  Из командной строки ДОС
  •  ошибка при n=7 и физической памяти выделено 420 Кб
  1.  Откомпилированная под MS Windows компилятором  Borland C++ 4.5 в режиме EasyWin
  •  ошибка при n=257 и памяти выделено 15Мб, в том числе и виртуальная память под Windows

Стандартные исключения базового класса exception

Производный класс logic_error (логические ошибки) включает исключения:

  •  bad_cast (ошибка приведения)
  •  out_of_range (вне диапазона)
  •  bad_typeid (ошибка оператора typeid())

Производный класс runtime_error (ошибки времени выполнения) включает исключения:

  •  range_error (ошибка диапазона)
  •  overflow_error (переполнение)
  •  bad_alloc (ошибка размещения)

Пример #31. Тестирование приведения типов, использующая RTTI 

#include <iostream.h>

#include <typeinfo.h>//class __rtti typeinfo

#include <stdexception.h>//class exception

using namespace std;

class A {public:

 virtual void foo(){cout<<“in A”<<endl;}}

class B: public A 

{public:

 void foo(){cout<<“in B”<<endl;}}

// главная программа

int main()

{ try{ A a, *pa; B b, *pb;

 pa=&b;

 pb=dynamic_cast<B*>(pa);//удачно

 pb->foo();

 pa=&a;

 pb=dynamic_cast<B*>(pa);//неудачно

 pb->foo(); }

catch(bad_cast){cout<<“Bad cast\n”;}

  return 0;

}


 

А также другие работы, которые могут Вас заинтересовать

74167. ОРГАНИЧЕСКИЙ МИР ПОЗДНЕГО ПАЛЕОЗОЯ 137.98 KB
  Численность многих групп морских животных уменьшилась плеченогие мшанки морские ежи офиуры аммоноидии наутилусы остракоды губки фораминиферы как и их разнообразие вплоть до полного вымирания целых классов трилобиты эвриптериды бластоидеи палеозойские группы морских лилий тетракораллы. В этот период вымерло 96 всех морских видов и 70 наземных видов позвоночных.
74168. Органический мир мезозоя 12.01 KB
  Органический мир мезозоя В мезозое вымирают гигантские папоротники древесные хвощи плауны. В юрском периоде вымирают семенные папоротники и появляются первые покрытосеменные растения тогда представленные только древесными формами постепенно распространившиеся на все материки. Вымирают растительноядные за ними хищные динозавры. В морях вымирают многие формы беспозвоночных и морские ящеры.
74169. Суть Теории Большого Взрыва 13.4 KB
  Суть Теории Большого Взрыва Теория Большого взрыва строится на том что материя и энергия из которых состоит все сущее но Вселенной ранее находились в сингулярном состоянии т. Изначально теория Большого взрыва носила название динамическая эволюционирующая модель. На данный момент теория Большого взрыва разработана настолько хорошо что ученые берутся описать процессы которые начали происходить во Вселенной через 10 43 с после Большого взрыва. Существует несколько доказательств теории Большого взрыва одним из которых является реликтовое...
74171. Области байкальской складчатости (образованы в среднем и позднем протерозое) 11.61 KB
  Области байкальской складчатости образованы в среднем и позднем протерозое: БайкалоЕнисейская СевероТаймырская ТиманоПечорская БайкалоЕнисейская складчатая область объединяет с востока на запад Байкальскую ВосточноСаянскую и Енисейскую области складчатости. На востоке граничит с Алданским щитом на северозападе с ЗападноСибирской платформой. СевероТаймырская складчатая область включает север полуострова Таймыр и острова Северная Земля. ТиманоПечорская складчатая область включает крайний северовосток европейской России.
74172. Эпигерцинские платформы (плиты) РФ и сопредельных территорий (название, расположение) 1.14 MB
  С юга Туранская плита ограничена молодыми горными сооружениями Копет-Дага и альпийским предгорным прогибом, а с юго-востока - глыбово-складчатыми структурами эпиплатформенного подвижного пояса Средней Азии.
74173. Состав и строение пород карбона Подмосковья Восточно-Европейской платформ 3.47 KB
  Нижний отдел представлен загипсованными глинами турнейского яруса с маломощными прослоями бурых углей и известняков затем песками песчаниками и глинами визейского возраста с отдельными пластами известняка а также пластами бурого угля и наконец карбонатными породами известняками и доломитами и глинами намюрского яруса общей мощностью до 100 м на севере области и до 250 м на юге. Средний отдел карбона слагают в Подмосковье осадки московского яруса представленные также карбонатноглинистой толщей и подразделяющиеся на четыре горизонта....
74174. СОСТАВ И СТРОЕНИЕ ПОРОД АРХЕЯ И РАННЕГО ПРОТЕРОЗОЯ СИБИРСКОЙ ПЛАТФОРМЫ 10.96 KB
  Докембрийская Сибирская платформа занимает пространство между реками Енисей и Лена. Породы архея и протерозоя слагающие фундамент платформы имеют выходы в пределах Алданского щита Анабарского массива Байкальской складчатой зоны Енисейского массива и Туруханского поднятия.
74175. Состав и строение пород палеозоя Тимано-Печорской области байкалид 17.88 KB
  Отложения нижнего-среднего ордовика представлены базальной (в основании лежащей) терригенной (обломочный материал, образованный в результате выветривания, эрозии и денудации) формацией, сменяемой карбонатами верхнего ордовика, силура и нижнего девона.