'

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

Понравилась презентация – покажи это...





Слайд 0

Обработка исключительных ситуаций Исключительная ситуация (исключение) – это ошибка, возникающая во время выполнения программы. Например, ошибка работы с файлом, деление на ноль, обращение по несуществующему адресу памяти. С++ позволяет программисту возможность реагировать на исключения и обрабатывать их. Механизм обработки исключений предназначен только для событий, которые происходят во время работы самой программы и указываются явным образом.


Слайд 1

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


Слайд 2

Контролируемый блок Контролируемый блок – код, внутри которого может произойти исключение. При этом контролируются все вложенные вызовы функций. try { // операторы } catch(тип1 имя1) { //обработка исключения 1 } … catch(тип_n имя_n) { //обработка исключения n }


Слайд 3

Обработчик исключений Обработчик начинается со слова catch, за которым следует в скобках тип исключения. Обработчики должны располагаться непосредственно после блока try. Если указать вместо параметра многоточие (…), то обработчик будет обрабатывать исключения любых типов. После обработки исключения управление передается первому оператору, следующему за всеми обработчиками.


Слайд 4

Порождение исключения throw выражение; Тип выражения определяет тип исключения. Обычно используются специальные классы исключений. throw без параметров используется внутри обработчика исключения для передачи исключения на более высокий уровень обработки. При поиске обработчика исключений автоматически вызываются деструкторы локальных объектов.


Слайд 5

Пример обработки исключений #include <iostream.h> template <class Data = char , int Max = 1000> class stack { private: Data st[Max]; int top; public: class StackError { }; stack (): top(0) {} void push(Data x) { if (top >= Max) throw StackError(); st[top++] = x; } Data pop() { if (top <= 0) throw StackError(); return st[--top]; } bool empty() { return ! top;} };


Слайд 6

Пример обработки исключений int main() { stack <char,2> s1; try { s1.push('a'); s1.push('b'); s1.push('c'); cout << "1: " << s1.pop() << endl; cout << "2: " << s1.pop() << endl; cout << "3: " << s1.pop() << endl; } catch (stack<char,2>::StackError) { cout <<"Error"<<endl; } cin.get(); return 0; }


Слайд 7

Использование разных классов исключений #include <iostream.h> template <class Data = char , int Max = 1000> class stack { private: Data st[Max]; int top; public: class Full { }; class Empty { }; stack (): top(0) {} void push(Data x) { if (top >= Max) throw Full(); st[top++] = x; } Data pop() { if (top <= 0) throw Empty(); return st[--top]; } bool empty() { return ! top;} };


Слайд 8

Использование разных классов исключений int main() { stack <char,2> s1; try { s1.push('a'); s1.push('b'); // s1.push('c'); cout << "1: " << s1.pop() << endl; cout << "2: " << s1.pop() << endl; cout << "3: " << s1.pop() << endl; } catch (stack <char,2> :: Full) { cout <<"Full"<<endl;} catch (stack <char,2> :: Empty){ cout <<"Empty"<<endl;} catch (...) { cout <<"Unknown error"<<endl; } cin.get(); return 0; }


Слайд 9

Исключения с аргументами template <class Data = char , int Max = 1000> class stack { private: Data st[Max]; int top; public: class Error { public: char sender[20], err[20]; Error( char *s, char *t) { strcpy(sender,s); strcpy(err,t); } }; void push(Data x) { if (top >= Max) throw Error("Push","Full"); st[top++] = x; } Data pop() { if (top <= 0) throw Error("Pop","Empty"); return st[--top]; } };


Слайд 10

Исключения с аргументами int main() { stack <char,2> s1; try { s1.push('a'); s1.push('b'); s1.push('c'); cout << "1: " << s1.pop() << endl; cout << "2: " << s1.pop() << endl; cout << "3: " << s1.pop() << endl; } catch (stack <char,2> :: Error ex) { cout <<"Error "<<ex.err<<" in " << ex.sender<<endl; } cin.get(); return 0; }


Слайд 11

Встроенные исключения Стандартная библиотека C++ содержит несколько предопределенных классов исключений. Все они имеют общего предка exception. Примеры: bad_alloc – ошибка при распределении памяти; invalid_argument – непр. аргумент ф-ции и т.д.


Слайд 12

Многофайловые программы При коллективной разработке больших программ неизбежно возникает необходимость использования нескольких исходных файлов. Обычно каждый файл содержит описание нескольких функций или классов. Рассмотрим создание библиотек классов.


Слайд 13

Библиотека классов Библиотека состоит из интерфейса (объявления функций и классов) и реализации (тел функций и методов). Интерфейс представляет собой заголовочный файл с объявлениями с расширением .H. Реализация – откомпилированный объектный (OBJ) или библиотечный (LIB) файл.


Слайд 14

Сборка многофайловых программ Заголовочный файл с интерфейсом включается в любой исходный файл, использующий классы, при помощи #include. Исходные и заголовочные файлы для компиляции включаются в файл проекта (BPR, DEV, DSP). В этом файле хранится информация о дате файлов, что позволяет перекомпилировать только измененные файлы.


Слайд 15

Межфайловые переменные Переменная должна быть определена только в одном файле, в других – объявлена с помощью extern. Чтобы определить переменные с одинаковыми именами в разных файлах, используется static. //файл A int Var; static int X; //файл B extern int Var; static int X; Var = 10;


Слайд 16

Межфайловые функции и классы. Функция определяется в одном файле, а объявляется во всех, которые ее используют. Чтобы определить функции с одинаковыми именами в разных файлах, используется static. Классы должны быть определены во всех файлах, где используются. Поэтому обычно классы определяются в заголовочных файлах и включаются во все файлы, где используются классы. Определения методов должны быть в единственном экземпляре в любых файлах, использующих заголовочный файл. Определения шаблонов функций и классов обязательно должны включаться в каждый файл, поэтому они размещаются в заголовочном файле.


Слайд 17

Пример определения классов //stack.h class stack { private: char st[100]; int top; public: stack (): top(0) {} void push (char x); char pop(); bool empty(); };


Слайд 18

Пример определения классов // stack.cpp #include “stack.h” void stack::push(char x) {st[top++] = x; } char stack:: pop() { return st[--top]; }


Слайд 19

Ошибки повторного включения Определение функции или переменной не должно включаться в файл дважды. //headtwo.h int Var; //headone.h #include “headtwo.h” // app.cpp #include “headone.h” #include “headtwo.h”


Слайд 20

Директивы препроцессора Для предупреждения повторного включения используются директивы препроцессора. #define имя // определение константы #if выражение //условная компиляция … #elif выражение … #else … #endif В выражениях можно проверить, определена ли константа с помощью defined(имя).


Слайд 21

Пример предотвращения повторного включения //stack.h #if !defined (STACK) #define STACK class stack { private: char st[100]; int top; public: stack (): top(0) {} void push (char x); char pop(); bool empty(); }; #endif


Слайд 22

Пространства имен В С++ для предотвращения конфликта имен функций и классов в разных файлах одного проекта можно использовать пространства имен. Пространство имен – именованная область файла. Пространство имен содержит описание переменных, функций, типов, классов.


Слайд 23

Описание пространства имен namespace имя { … } Пример: namespace math { const double pi = 3.1415926; double len (double r) { return 2 * pi * r; } }


Слайд 24

Доступ к членам пространства имен Доступ осуществляется через область видимости cout << math :: pi; либо с использованием описания using namespace имя using namespace math; cout << pi; Директива using действует до конца блока.


Слайд 25

Неоднократное определение пространства имен Определения пространства имен могут встречаться в программе неоднократно. namespace math { const double pi = 3.1415926;} … namespace math { double len (double r) { return 2 * pi * r; } } В этом случае второе определение является продолжением первого. В стандартной библиотеке C++ большинство классов описаны в пространстве имен std. Можно описать неименованное пространство имен. Оно получит имя, совпадающее с именем файла.


×

HTML:





Ссылка: