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;

}


 

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

44587. Основные типы протоколов 39.5 KB
  Протоколы этих стеков выполняют работу специальную для своего уровня. Однако коммуникационные задачи которые возложены на сеть приводят к разделению протоколов на три типа: прикладные протоколы; транспортные протоколы и сетевые протоколы. Уровни модели OSI и соответствующие им типы протоколов Прикладные протоколы работают на верхнем уровне модели OSI и обеспечивают взаимодействие приложений и обмен данными между ними. Транспортные протоколы поддерживают сеансы связи между компьютерами и гарантируют надежный обмен данными между ними.
44588. Наиболее распространенные стеки протоколов 32.5 KB
  Стек TCP IP включает в себя два основных протокола: TCP Trnsmission Control Protocol протокол для гарантированной доставки данных разбитых на последовательность фрагментов. IP Internet Protocol протокол для передачи пакетов относится к разряду сетевых протоколов. Стек TCP IP является промышленным стандартным набором протоколов которые обеспечивают связь в неоднородной среде т.
44589. Передача данных по сети 53.5 KB
  Пример передачи данных 1 Компьютер-отправитель устанавливает соединение с принтсервером. Если бы использовался более сложный протокол и соответствующие ему сетевые службы то время передачи увеличилось бы но зато повысилась бы достоверность передачи. Указанный в пакете адрес отправителя в этом случае использовался бы сетевой службой для формирования подтверждения и передачи его соответствующему приемнику.
44590. Стандарт 10BaseT 39.5 KB
  ЛВС стандарта 10BseT может обслуживать до 1024 компьютеров. Сеть стандарта 10BseT Достоинством является возможность использования распределительных стоек и панелей коммутации что позволяет легко перекоммутировать сеть или добавить новый узел без остановки работы сети.
44591. Стандарт 10Base2 59 KB
  С использованием репитеров может быть увеличена общая протяженность сети введением дополнительных сегментов. Два из пяти сегментов являются межрепитерными связями и служат только для увеличения длины сети . Максимальное число компьютеров до 1024 а общая длина сети до 925м.
44592. Стандарт 10Base5 38.5 KB
  Главный кабель к которому подключаются трансиверы для связи с РС имеет длину до 500 м и возможность подключения до 100 компьютеров. С использованием репитеров которые также подключаются к магистральному сегменту через трансиверы общая длина сети может составить 2500 м.
44593. Стандарт 10BaseFL 43 KB
  Сеть стандарта 10BseFL Особенность этих трансиверов в том что их передатчики преобразуют электрические сигналы от ЭВМ в световые импульсы а приемники световые в электрические. Популярность использования 10BseFL обусловлена: высокой помехозащищенностью; возможностью прокладки кабеля между репитерами на большие расстояния т.
44594. Стандарт 100BaseX Ethernet 40.5 KB
  Его особенностью является то что он сохранил стандартный для Ethernet метод доступа CSM CD от которого отходили разработчики других технологий повышенной скорости передачи в сети. Сохранение метода доступа означает что имеющиеся в наличие драйверы для Ethernet будут работать без изменений. Преимуществом этой технологии появившейся в конце 1993 года является то что степень ее совместимости с Ethernetсетями позволяет интегрировать ее в эти сети с помощью двухскоростных сетевых адаптеров или мостов.