Разделы презентаций


Лекция 24.03.2014 г. 1 Исключения и обработка исключений (примеры программ)

Содержание

Лекция 24.03.2014 г.Демонстрация обработки исключенийПрограмма демонстрирует генерацию (запуск) исключения, его перехват и обработку. Важно уяснить, что при генерации исключения сначала происходит разрушение всех локальных объектов, а уже потом – переход к

Слайды и текст этой презентации

Слайд 1Лекция 24.03.2014 г.
Исключения и обработка исключений
(примеры программ)

Лекция 24.03.2014 г.Исключения и обработка исключений(примеры программ)

Слайд 2Лекция 24.03.2014 г.
Демонстрация обработки исключений
Программа демонстрирует генерацию (запуск) исключения, его

перехват и обработку. Важно уяснить, что при генерации исключения сначала

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

//Программа Ex005.cpp
#include
using namespace std;
class SomeClass {
public:
SomeClass() { cout << "start SomeClass()" << endl; }
~SomeClass() { cout << "start ~SomeClass()" << endl; }
};
void oz() {
SomeClass rb;
for(int i = 0; i < 3; i++) cout << "inside a function oz...\n";
throw 47;
}
int main() {
try { cout << "start main...\n”; oz();}
catch (int) {
cout << "inside catch(int)\n”;
}
}

Лекция 24.03.2014 г.Демонстрация обработки исключенийПрограмма демонстрирует генерацию (запуск) исключения, его перехват и обработку. Важно уяснить, что при

Слайд 3Лекция 24.03.2014 г.
Демонстрация обработки исключений
Программа демонстрирует, как обработчик исключений базового

класса перехватывает исключение производного класса (маскирует его)
//Программа Ex006.cpp
#include
using namespace

std;
class X {
public:
class Trouble {};
class Small : public Trouble {};
class Big : public Trouble {};
void f() { throw Big(); }
};
int main() {
X x;
try { x.f(); }
catch(X::Trouble&) { cout << "caught Trouble" << endl; }
catch(X::Small&) { cout << "caught Small Trouble" << endl; }
catch(X::Big&) { cout << "caught Big Trouble" << endl; }
}
Лекция 24.03.2014 г.Демонстрация обработки исключенийПрограмма демонстрирует, как обработчик исключений базового класса перехватывает исключение производного класса (маскирует его)//Программа

Слайд 4Лекция 24.03.2014 г.
Демонстрация обработки исключений
В этой программе обработчики размещены в

правильном порядке: сначала – производные классы, а за ними –

базовый класс

//Программа Ex006.cpp
#include
using namespace std;
class X {
public:
class Trouble {};
class Small : public Trouble {};
class Big : public Trouble {};
void f() { throw Big(); }
};
int main() {
X x;
try { x.f(); }
catch(X::Small&) { cout << "caught Small Trouble" << endl; }
catch(X::Big&) { cout << "caught Big Trouble" << endl; }
catch(X::Trouble&) { cout << "caught Trouble" << endl; }
}

Лекция 24.03.2014 г.Демонстрация обработки исключенийВ этой программе обработчики размещены в правильном порядке: сначала – производные классы, а

Слайд 5Лекция 24.03.2014 г.
Демонстрация обработки исключений
Еще один пример с иерархией исключений
//Программа

Ex004.cpp
#include
#include
using namespace std;
class Matherr {
public:
virtual

void debug_print() const {
cout << "Math_error" << endl;
}
};
class Int_overflow : public Matherr {
const char* op;
int a1, a2;
public:
Int_overflow(const char* p, int a, int b) : op(p), a1(a), a2(b) {}
virtual void debug_print() const {
cout << "Int_overflow: " << op << '(' << a1 << ',' << a2 << ')' << endl;
}
};
int add(int x, int y) {
if((x > 0 && y > 0 && x > INT_MAX-y) || (x < 0 && y < 0 && x < INT_MIN-y))
throw Int_overflow("+", x, y);
return x+y;
}
// Продолжение на следующем слайде...
Лекция 24.03.2014 г.Демонстрация обработки исключенийЕще один пример с иерархией исключений//Программа Ex004.cpp#include #include using namespace std;class Matherr {

Слайд 6Лекция 24.03.2014 г.
Демонстрация обработки исключений
void f() {
try {

int i1 = add(1, 2);
int i2 = add(INT_MAX,

-2);
int i3 = add(INT_MAX, 2);
}
catch(Matherr& m) {
//catch(Matherr m) {
m.debug_print();
}
}
int main() {
f();
return 0;
}
Лекция 24.03.2014 г.Демонстрация обработки исключенийvoid f() { try {  int i1 = add(1, 2);  int

Слайд 7Лекция 24.03.2014 г.
Не перехваченные исключения
Если ни один из обработчиков, следующих

за блоком try, не соответствует типу исключения, то исключение передается

в контекст следующего уровня (выше по цепочке вызовов), пока не будет найден подходящий обработчик. Если такой обработчик не находится, автоматически вызывается стандартная библиотечная функция terminate(), которая, в свою очередь, вызывает функцию abort() из стандартной библиотеки С, что приводит к аварийному завершению программы (при этом деструкторы глобальных и статических объектов не вызываются!).

Функция terminate() также запускается в том случае, если деструктор локального объекта генерирует исключение в процессе раскрутки стека (во время обработки текущего исключения).

!!! Можно заменить стандартную функцию terminate() собственной версией подобной функции при помощи стандартной функции set_terminate()
Лекция 24.03.2014 г.Не перехваченные исключенияЕсли ни один из обработчиков, следующих за блоком try, не соответствует типу исключения,

Слайд 8Лекция 24.03.2014 г.
Не перехваченные исключения
//Программа Ex008.cpp
#include
#include
#include
using namespace

std;
void MyTerminate() {
cout

(*old_terminate)() = set_terminate(MyTerminate);
class BadClass {
public:
class A{};
void f() {
cout << "inside BadClass::f()" << endl;
throw A();
}
~BadClass() {
cout << "inside ~BadClass()..." << endl;
throw 'c';
}
};
int main() {
try { BadClass b; b.f(); }
catch(...) { cout << "inside catch(...)" << endl; }
}
Лекция 24.03.2014 г.Не перехваченные исключения//Программа Ex008.cpp#include #include #include using namespace std;void MyTerminate() { cout

Слайд 9Лекция 24.03.2014 г.
Зачистка
Одно из преимуществ обработки исключений состоит в том,

что нормальный ход программы прерывается и управление сразу передается в

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

Слайд 10Лекция 24.03.2014 г.
Зачистка
//Программа Ex009.cpp
#include
using namespace std;
class Trace {

static int counter;
int objid;
public:
Trace() {

objid = counter++;
cout << "constructing Trace #" << objid << endl;
if(objid == 3) throw objid;
}
~Trace() { cout << "destructing Trace #" << objid << endl; }
};
int Trace::counter = 0;

int main() {
try {
Trace n1;
Trace array[5]; // Не все эл. создаются
Trace n2; // Сюда не попадаем
}
catch(int i) { cout << "caught " << i << endl; }
}
Лекция 24.03.2014 г.Зачистка//Программа Ex009.cpp#include using namespace std;class Trace {  static int counter;  int objid; public:

Слайд 11Лекция 24.03.2014 г.
Управление ресурсами
Одно из преимуществ обработки исключений состоит в

том, что нормальный ход программы прерывается и управление сразу передается

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

Слайд 12Лекция 24.03.2014 г.
Управление ресурсами
//Программа Ex010.cpp Зависшие указатели
#include
#include
using

namespace std;
class Cat {
public:
Cat() { cout

endl; }
~Cat() { cout << "~Cat()" << endl; }
};
class Dog {
public:
void* operator new(size_t sz) {
cout << "allocating a Dog" << endl; throw 47; // Имитация нехватки памяти
}
void operator delete(void* p) {
cout << "deallocating a Dog" << endl; ::operator delete(p);
}
};
class UseResources {
Cat* bp;
Dog* op;
public:
UseResources(int count = 1) {
cout << "UseResources()" << endl;
bp = new Cat[count]; op = new Dog;
}
~UseResources() {
cout << "~UseResources()" << endl;
delete [] bp; // Уничтожение массива
delete op;
}
};
int main() {
try { UseResources ur(3); }
catch(int) { cout << "inside handler" << endl; }
} // В результате имеем 4 зависших указателя!
Лекция 24.03.2014 г.Управление ресурсами//Программа Ex010.cpp  Зависшие указатели#include #include using namespace std;class Cat {public: Cat() { cout

Слайд 13Лекция 24.03.2014 г.
Управление ресурсами на уровне объектов
Чтобы предотвратить утечку ресурсов,

как это было в предыдущей программе, необходим о отказаться от

«низкоуровневого» выделения ресурсов одним из следующих способов:
перехват исключений внутри конструктора с последующим освобождением ресурса;
выделение ресурсов только в конструкторе объекта, чтобы освобождение ресурсов могло выполняться внутри деструктора.
Во втором варианте каждая операция выделения ресурсов становится «атомарной» (является частью жизненного цикла локального объекта). Если выделение ресурса завершается неудачей, другие объекты будут корректно уничтожены в процессе раскрутки стека. Эта методика называется получением ресурсов при инициализации.
В следующей программе эта задача решается с помощью шаблона – «обертки» для указателей. Конструкторы объектов, созданных на основе данного шаблона, вызываются до основного кода конструктора UseResurces, и для любого конструктора, завершившегося до возникновения исключения, в процессе раскрутки стека будет вызван соответствующий деструктор.
Лекция 24.03.2014 г.Управление ресурсами на уровне объектовЧтобы предотвратить утечку ресурсов, как это было в предыдущей программе, необходим

Слайд 14Лекция 24.03.2014 г.
Управление ресурсами на уровне объектов
//Программа Ex011.cpp Безопасные, атомарные

указатели
#include
#include
using namespace std;
template

class PWrap {// Шаблон – «обертка» для указателей
T* ptr;
public:
class RangeError {}; // класс исключения
PWrap() {
ptr = new T[sz];
cout << "PWrap constructor completed" << endl;
}
~PWrap() {
delete [] ptr;
cout << "PWrap destructor completed" << endl;
}
T& operator[](int i) throw(RangeError) {
if(i >= 0 && i < sz) return ptr[i];
throw RangeError();
}
};
// Продолжение на следующем слайде ...
Лекция 24.03.2014 г.Управление ресурсами на уровне объектов//Программа Ex011.cpp Безопасные, атомарные указатели#include #include using namespace std;template class PWrap

Слайд 15Лекция 24.03.2014 г.
Управление ресурсами на уровне объектов
// Начало на предудущем

слайде …
class Cat {
public:
Cat() { cout

endl; }
~Cat() { cout << "~Cat()" << endl; }
};

class Dog {
public:
void* operator new[](size_t) { // Имитация нехватки памяти
cout << "Allocating a Dog" << endl;
throw 47;
}
void operator delete[](void* p) {
cout << "Deallocating a Dog" << endl;
::operator delete[](p);
}
};
// Продолжение на следующем слайде …
Лекция 24.03.2014 г.Управление ресурсами на уровне объектов// Начало на предудущем слайде …class Cat {public: Cat() { cout

Слайд 16Лекция 24.03.2014 г.
Управление ресурсами на уровне объектов
class UseResources {
PWrap

3> cats; // Создаем 3 «кота»
PWrap dog; // Создаем

одну «собаку», и при вызове перегруженной операции
// new получаем исключение...
public:
UseResources() {
cout << "UseResources()" << endl;
}
~UseResources() {
cout << "~UseResources()" << endl;
}
};

int main() {
try {
UseResources ur;
}
catch(int) {
cout << "inside handler" << endl;
}
catch(...) {
cout << "inside catch(...)" << endl;
}
}
Лекция 24.03.2014 г.Управление ресурсами на уровне объектовclass UseResources { PWrap cats; // Создаем 3 «кота» PWrap dog;

Слайд 17Лекция 24.03.2014 г.
Блоки try уровня функций
Исключения при выполнении конструкторов происходят

достаточно часто. Пусть, например, мы хотим обработать исключения, происходящие при

инициализации вложенных объектов или подобъектов базовых классов.
Для этого инициализация таких подобъектов заключается в блоки try уровня функций.
В отличие от обычного синтаксиса, блоком try для инициализаторов конструкторов является само тело конструктора (см. пример на след. слайде).
Лекция 24.03.2014 г.Блоки try уровня функцийИсключения при выполнении конструкторов происходят достаточно часто. Пусть, например, мы хотим обработать

Слайд 18Лекция 24.03.2014 г.
Блоки try уровня функций
// Обработка исключений в подобъектах
#include


using namespace std;
class Base {
int i;
public:
class BaseExcept {};

Base(int i) : i(i) { throw BaseExcept(); }
};
class Derived : public Base {
public:
class DerivedExcept {
const char* msg;
public:
DerivedExcept(const char* msg) : msg(msg) {}
const char* what() const { return msg; }
};
Derived(int j) try : Base(j) {
cout << "This won't print" << endl;
}
catch (BaseExcept&) {
throw DerivedExcept("Base subobject threw");;
}
};
int main() {
try { Derived d(3); }
catch (Derived::DerivedExcept& d) { cout << d.what() << endl; }
}
Лекция 24.03.2014 г.Блоки try уровня функций// Обработка исключений в подобъектах#include using namespace std;class Base { int i;public:

Слайд 19Лекция 24.03.2014 г.
Блоки try уровня функций
Следующий пример показывает, что допускается

создание блоков try уровня функции для любых функций, в том

числе и для main:

// Блоки try уровня функций
#include
using namespace std;
int main() try {
cout << "start main..." << endl;
throw "exception main";
}
catch(const char* msg) {
cout << msg << endl;
return 1;
}

Лекция 24.03.2014 г.Блоки try уровня функцийСледующий пример показывает, что допускается создание блоков try уровня функции для любых

Слайд 20Лекция 24.03.2014 г.
Стандартные исключения
Исключения стандартной библиотеки могут использоваться в пользовательских

программах. Как правило, проще и удобнее начать со стандартного класса

исключения, чем пытаться определять собственный класс. Даже если стандартный класс делает не совсем то, что нужно, на его основе всегда можно создать производный класс.
Все стандартные классы исключений в конечном счете являются производными от класса exception (см. след. слайд). Его основными подклассами являются logic_error и runtime_error, которые имеют конструкторы со строковыми аргументами. Это позволяет сохранить сообщение в объекте исключения и извлечь его позднее с помощью функции exception::what().
Лекция 24.03.2014 г.Стандартные исключенияИсключения стандартной библиотеки могут использоваться в пользовательских программах. Как правило, проще и удобнее начать

Слайд 21Лекция 24.03.2014 г.
exception
logic_error
bad_alloc
bad_exception
ios_base::failure
bad_typeid
bad_cast
runtime_error
length_error
domain_error
out_of_range
invalid_argument
underflow_error
overflow_error
range_error
Иерархия стандартных классов для исключений
exception
typeinfo
stdexcep
new
ios
Заголовочные файлы:

Лекция 24.03.2014 г.exceptionlogic_errorbad_allocbad_exceptionios_base::failurebad_typeidbad_castruntime_errorlength_errordomain_errorout_of_rangeinvalid_argumentunderflow_erroroverflow_errorrange_errorИерархия стандартных классов для исключенийexceptiontypeinfostdexcepnewiosЗаголовочные файлы:

Слайд 22Лекция 24.03.2014 г.
Стандартные исключения
// Создание класса исключения, производного от std::runtime_error
#include


#include
using namespace std;

class MyError : public runtime_error {
public:
MyError(const

string& msg = "") : runtime_error(msg) {}
};

int main() {
try {
throw MyError("my message");
}
catch (MyError& x) {
cout << x.what() << endl;
}
}
Лекция 24.03.2014 г.Стандартные исключения// Создание класса исключения, производного от std::runtime_error#include #include using namespace std;class MyError : public

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика