Similar presentations:
except
1.
Исключения2. Исключительные ситуации
При работе программ возникают т.н. исключительныеситуации, когда дальнейшее нормальное выполнение
приложения становится невозможным.
Причиной исключительных ситуаций могут быть:
ошибки в программе;
неправильные действия пользователя;
неверные данные и т.д.
3. Классификация исключительных ситуаций
Различают два основных типа исключений:исключения C++;
системные исключения.
Первый тип исключений генерируется в самой
программе инструкцией throw.
Второй тип исключений генерируется операционной
системой.
4. Режимы компиляции для работы с исключительными ситуациями
Для того чтобы обеспечить перехват исключений C++,необходимо включить режим компиляции /EHsc, а для
перехвата исключений любого типа – режим /EHa.
Кроме того, для перехвата системных исключений,
связанных с обработкой данных с плавающей точкой,
следует включить режим /fp:except.
5. Переключение режимов компиляции для перехвата исключений
6. Инструкции С++ для работы с исключительными ситуациями
Язык C++ включает следующие возможности дляработы с исключениями:
создание защищенных блоков (try-блок) и перехват
исключений (catch-блок);
инициализация исключений (инструкция throw).
7. Защищённый блок
Простейший формат защищенного блока имеет видtry {операторы_защищенного_блока}
catch(...) {обработчик_исключительной_ситуации}
Многоточие является частью синтаксиса языка!
8. Механизм работы защищённого блока
Выполняются инструкции, входящие в состав блокаtry (защищенный блок).
Если при их выполнении исключение не возбуждается,
то блок catch пропускается.
При выбросе исключения выполнение защищенного
блока прекращается, и начинают работать инструкции,
записанные в блоке catch.
После окончания работы блока catch исключение
считается обработанным, и управление передается на
первую инструкцию, следующую за конструкцией try
…catch.
9. Пример выброса исключения (системные исключения)
int x = 0;try {
cout <<2/x; // Здесь произойдет выброс исключения
// Последующие операторы выполняться не будут
}
catch (...) {
cout << "Division by zero" << endl;
}
Для корректной работы этого примера необходимо
включить режим компиляции /EHa
10. Возбуждение собственных исключений
Для возбуждения собственных исключенийиспользуется оператор
throw выражение
Тип выражения, указанного в операторе throw,
определяет тип исключительной ситуации, а значение
может быть передано обработчику исключений.
11. Полный формат защищённого блока
try {операторы_защищенного_блока}catch-блоки
Catch-блок имеет один из следующих форматов:
catch (тип) {обработчик_исключения}
catch (тип идентификатор) {обработчик_исключения}
catch (...) {обработчик_исключения}
Первый формат используется, если нам надо указать
тип перехватываемого исключения, но не нужно
обрабатывать связанное с этим исключением значение
(это достигается при использовании второго формата
оператора catch). Наконец, третий формат оператора
catch позволяет обработать все исключения (в том
числе и системные).
12. Пример выброса исключения (собственные исключения)
try {…
throw 0;
//Здесь произойдет выброс исключения
// Последующие операторы выполняться не будут
}
catch (...) {
cout << “Everything fail!” << ‘\n’;
}
13. Пример выброса исключения (собственные исключения)
try {…
throw 0;
//Здесь произойдет выброс исключения
// Последующие операторы выполняться не будут
}
catch (int) {
cout << ”Int type exception was thrown!” << ‘\n’;
}
catch (...) {
cout << ”Everything fail!” <<‘\n’;
// этот блок не будет работать
}
14. Пример выброса исключения (собственные исключения)
try {…
throw 0;
//Здесь произойдет выброс исключения
// Последующие операторы выполняться не будут
}
catch (int e) {
cout << ”Int type exception was thrown, code is ”
<< e << endl;
}
catch (...) {
cout << ”Everything fail!” << endl;
// этот блок не будет работать
}
15. Последовательность действий при обработке исключений
Создается статическая переменная со значением,заданным в операторе throw. Она будет
существовать до тех пор, пока исключение не будет
обработано.
Завершается выполнение защищенного try-блока:
раскручивается стек подпрограмм, корректно
уничтожаются объекты, время жизни которых
истекает и т.д.
Выполняется поиск первого из catch-блоков,
который пригоден для обработки созданного
исключения.
16. Последовательность действий при обработке исключений (продолжение)
Поиск catch-блоков ведется по следующим критериям:тип, указанный в catch-блоке, совпадает с типом
созданного исключения, или является ссылкой на этот
тип;
указатель, заданный в операторе throw, может быть
преобразован по стандартным правилам к указателю,
заданному в catch-блоке.
в операторе throw задано многоточие.
Если нужный обработчик найден, то ему передается
управление и, при необходимости, значение,
вычисленное в операторе throw. Оставшиеся catchблоки игнорируются.
17. Последовательность действий при обработке исключений (продолжение)
Если ни один из catch-блоков, указанных послезащищенного блока, не сработал, то исключение
считается необработанным. Его обработка может быть
продолжена во внешних блоках try (если они, конечно,
есть!).
В конце оператора catch может стоять оператор throw
без параметров. В этом случае работа catch-блока
считается незавершенной а исключение – не
обработанным до конца, и происходит поиск
соответствующего обработчика на более высоких
уровнях.
18. Пример обработки исключений (1)
#include <fstream.h>class Hello{
public:
Hello(){cout « "Hello!" « endl;}
~Hello(){cout « "Bye!" « endl;}
};
void fl(){
ifstream ifs(“BAD_FILE_NAME");
if (!ifs){
cout « "Генерируем исключение" « endl:
throw "Ошибка при открытии файла“;
}
}
void f2(){
Hello H; // Создаем локальный объект
fl();
// Вызываем функцию, генерирующую
исключение
}
22.04.2026
18
19. Пример обработки исключений (2)
int main(){try{
cout « "Входим в try-блок" « endl;
f2();
cout « "Выходим из try-блока" « endl;
}
catch(int i){
cout « "Вызван обработчик int. исключение - " « i «
endl;
return -1;
}
catch(const char * p){
cout « "Вызван обработчик const char*, исключение “
« p « endl;
return -1;
}
catch(...){
cout « "Вызван обработчик всех исключений" « endl;
return -1:
}
return 0;
}
22.04.2026
19
20. Пример обработки исключений (3)
Результаты выполнения программы:◦
◦
◦
◦
◦
Входим в try-блок
Hello!
Генерируем исключение
Bye!
Вызван обработчик const char *, исключение Ошибка при открытии файла
После порождения исключения был вызван
деструктор локального объекта, хотя
управление из функции f 1 было передано
обработчику находящемуся в функции main.
Сообщение «Выходим из try-блока» не было
ведено.
22.04.2026
20
21. Исключения в конструкторах и деструкторах
Язык C++ не позволяет возвращать значениеиз конструктора и деструктора.
Механизм исключений дает возможность
сообщить об ошибке, возникшей в
конструкторе или деструкторе объекта.
Этот же механизм можно использовать в
функциях, которые не возвращают значений
или должны возвращать значения
определенного типа.
22.04.2026
21
22. Пример использования исключений в конструкторе
const int MaxVectorSize = 32000;class Vector{
public:
class Size{};
// Класс исключения
Vector(int n){
if (n < 0 || n > MaxVectorSize)
throw Size;
...
}
При использовании класса Vector можно предусмотреть перехват исключений
типа Size.
try{
Vector *p = new Vector(i);
}
catch(Vector::Size){
... // Обработка ошибки размера вектора
}
22.04.2026
22
23. Свойства исключений в конструкторе
Если в конструкторе объекта генерируетсяисключение, автоматически вызываются
деструкторы для полностью созданных в этом блоке
к текущему моменту объектов, а также для полей
данных текущего объекта, являющихся объектами,
и для его базовых классов.
◦ Например, если исключение возникло при создании
массива объектов, деструкторы будут вызваны только для
успешно созданных элементов.
Если объект создается в динамической памяти с
помощью операции new и в конструкторе возникнет
исключение, память из-под объекта корректно
освобождается.
22.04.2026
23
24. Передача дополнительной информации об исключении
Для передачи дополнительной информации об возможном исключении можно создатьсобственный класс.
class Except{
public:
int type; // тип исключения
char msg[256];
// сообщение для пользователя
Except(int type,char *msg){
this->type= type;
strcpy(this->msg, msg);
}
};
void f1(){
…
throw Except(1,”Не могу открыть файл”);
…
throw Except(10,”Деление на 0”);
}
int main(){
try{
f1();
}
catch(Except ex){
switch(ex.type){
case 1:
…
22.04.2026
case …
24
25. Иерархии исключений
Использование собственных классов исключенийпредпочтительнее применения стандартных типов данных.
С помощью классов можно более гибко организовать
передачу информации об исключении, легче
дифференцировать обработку исключений, а кроме того,
появляется возможность использовать иерархии классов.
Поскольку механизм управления исключениями позволяет
создать обработчик для базового класса, родственные
исключения часто можно представить в виде иерархии.
Производя исключения от общего базового класса, можно в
обработчике перехватывать ссылку или указатель на базовый
класс, используя полиморфизм.
В зависимости от обстоятельств можно использовать либо
обработчик исключений базового класса, который будет
перехватывать и производные исключения, либо собственные
обработчики производных классов.
22.04.2026
25
26. Пример иерархии исключений
class Matherr{};class Overflow: public Matherr{}; // Переполнение
class Underflow: public Matherr{}; // Исчезновение порядка
class ZeroDivide: public Matherr{}; // Деление на ноль
class IOerr{};
class Readerr:
public IOerr{};
// Ошибка чтения
class Writerr:
public IOerr{};
// Ошибка записи
class Seekerr:
public IOerr{};
// Ошибка поиска
int main(){
try{
…
}
catch(IOErr){
…
}
catch(Overflow){
…
}
}
22.04.2026
26
27.
Стандартные классы исключенийexception
logic_error
runtime_error
length_error
domain_error
out_of_range
bad_alloc
bad_exception
bad_cast
range_error
bad_typeid
overflow_error
io_base::failure
underflow_error
invalid_argument
27
28.
Выбрасывание исключения (throw)Вариант 1: использовать простой тип
try
{
if (y == 0) throw std::string("Деление на ноль!");
z = x / y;
}
catch(const std::string& ex)
{
std::cerr << ex;
}
28
29.
Вариант 2: класс std::exceptiontry
{
if (y == 0) throw std::exception("Деление на ноль!");
z = x / y;
}
catch(std::exception& ex)
{
std::cerr << ex.what();
}
29
30.
Вариант 3: собственный классclass ExceptionDivideByZero : public std::exception
{
};
try
{
if (y == 0) throw ExceptionDivideByZero();
z = x / y;
}
catch(ExceptionDivideByZero)
{
std::cerr << "Деление на ноль!";
}
30
31.
Catch alltry
{
}
catch(...)
{
std::cerr << "Неизвестная ошибка!";
}
31
32.
Catch-цепочкаtry
{
}
catch(std::bad_alloc)
{
}
catch(std::bad_cast)
{
}
32
33.
try{
}
catch(std::exception)
{
}
catch(...)
{
}
catch(std::bad_alloc)
{
}
// ОШИБКА
33
34.
try{
}
catch(std::bad_alloc)
{
}
catch(std::exception)
{
}
catch(...)
{
}
// ВЕРНО
34
35.
Повторное выбрасывание исключенияtry
{
try
{
// Здесь произошла ошибка выделения памяти
}
catch(std::bad_alloc)
{
// Выдаем сообщение, и перевыбрасываем:
throw;
}
}
catch(std::exception)
{
// Заносим в лог
}
35
36. Работающие обработчики исключений (пример 1)
try { …try {
…
throw ”Error!”;
catch (int) {… }
catch (float) {… }
…} //внешний try
catch (char * c) { … }
catch (...) { …}
… } //внутренний try
37. Работающие обработчики исключений (пример 2)
try {…
try {
…
throw ”Error!”;
…
} //внутренний try
catch (char *) {…
}
catch (float) {…
}
…
} //внешний try
catch (char * c) {…
}
catch (...) { …
}
38. Работающие обработчики исключений (пример 3)
try {…
try {
…
throw ”Error!”;
…
} //внутренний try
catch (char *) {…
throw;
}
catch (float) {…
}
…
} //внешний try
catch (char * c) {…
}
catch (...) { …
}
39. Работающие обработчики исключений (пример 4)
try {…
try {
…
throw ”Error!”;
…
} //внутренний try
catch (void *) {…
throw;
}
catch (float) {…
}
…
} //внешний try
catch (char * c) {…
}
catch (...) { …
}
40. Работающие обработчики исключений (пример 5)
try {…
try {
…
throw ”Error!”;
…
} //внутренний try
catch (void *) {…
throw;
}
catch (float) {…
}
…
} //внешний try
catch (...) { …
} //ошибочный порядок записи!
catch (char * c) {…
}
41. Необработанное исключение
Если оператор throw был вызван вне защищенногоблока (что чаще всего случается, когда исключение
возбуждается в вызванной функции), или если не был
найден ни один подходящий обработчик этого
исключения, то вызывается стандартная функция
terminate(). Она, в свою очередь, вызывает функцию
abort() для завершения работы с приложением.
42. Собственная функция аварийного завершения
Можно зарегистрировать с помощью функцииset_terminate свою функцию, которая будет
выполняться перед аварийным завершением работы:
void MyTerminate() {
cout << "An error occured!" << endl;
exit(-1);
}
int main ()
{
set_terminate(MyTerminate);
…
throw 0;
}
43. Преимущества использования исключений
Реакция на исключение происходит всегда◦ Коды ошибок работают только тогда, когда их
проверяют
Возможность различной реакции на
различные типы исключений
Объекты, выбрасываемые при исключении
могут нести доп. информацию об
исключительной ситуации
◦ имя файла и номер строки, сообщение об ошибке,
код системной ошибки и т.п.
44. Проблемы
При использовании исключенийнеобходимо иметь представление о том,
какие исключения могут быть выброшены
в результате работы функции или метода
класса
Увеличение размеров машинного кода и
некоторое снижение его быстродействия
Необходимость разработки кода,
устойчивого к возникновению
45. Выброс исключения в конструкторе
При выбросе исключения в телеконструктора или в списке
инициализации процесс
конструирования экземпляра класса
прерывается и он считается не
созданным
◦ Деструктор для такого класса вызван не
будет
◦ Будут вызваны деструкторы для тех полей
класса, для которых успели выполниться
конструкторы
46.
class A{
public:
A(std::string const& name)
:m_name(name)
{
std::cout << "A::A(" << m_name << ")\n";
}
~A()
{
std::cout << "A::~A(" << m_name << ")\n";
}
private:
std::string m_name;
};
int main()
{
try
{
B b2("Test", 1000000000);
}
catch (std::bad_alloc const & e)
{
std::cout << "Error: " << e.what() << "\n";
}
return 0;
}
class B
{
public:
B(std::string const& name, size_t size)
:m_a(name)
,m_pData(new int[size])
,m_size(size)
{
std::cout << "B::B(" << m_size << ")\n";
}
~B()
{
delete [] m_pData;
std::cout << "B::~B(" << m_size << ")\n";
}
private:
A m_a;
Нехватка памяти и
size_t m_size;
int * m_pData;
выброс исключения
};
std::bad_alloc
Output:
A::A(Test)
A::~A(Test)
Error: bad allocation
47. Выброс исключений в деструкторе
Не допускайте выброса исключений вдеструкторах объектов
В C++ выброс исключения в
деструкторе приводит к аварийному
завершению работы программы
48. Exception-safe programming
Разработка кода, безопасного к возникновениюисключений
EXCEPTION-SAFE
PROGRAMMING
49. Код, устойчивый к возникновению исключений
Объект, как минимум, должен оставатьсяdestructible – последующий вызов
деструктора данного объекта не должен
приводить к сбою в приложении или
неопределенному поведению
◦ При выбросе исключений не должно
происходить утечек памяти и других ресурсов
◦ Объект, желательно, должен сохранить свою
целостность, т.е, последующие вызовы
методов объекта не должны приводить к
сбоям или неопределенному поведению
Желательно, объект должен вернуться в
предсказуемое состояние, а еще лучше, в
50.
class CMyString{
public:
CMyString(const char * str):m_size(strlen(str))
{
m_pChars = new char[m_size + 1];
memcpy(m_pChars, str, m_size);
m_pChars[m_size] = '\0';
}
CMyString(CMyString const& other)
:m_size(other.m_size)
,m_pChars(new char[other.m_size + 1])
{
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
~CMyString()
{
delete [] m_pChars;
}
CMyString& operator=(CMyString const& other)
{
if (this != &other)
{
delete [] m_pChars;
m_size = other.m_size;
m_pChars = new char[other.m_size + 1];
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
return *this;
}
private:
char * m_pChars;
size_t m_size;
};
Код конструктора безопасен к
возникновению исключений
Код конструктора копирования
безопасен к возникновению
исключений
Выброс исключения в операторе
new нарушит целостность
объекта и возможность его
корректного разрушения: в
деструкторе произойдет
повторное удаление массива
m_pChars.
51.
class CMyString{
public:
CMyString(const char * str):m_size(strlen(str))
{
m_pChars = new char[m_size + 1];
memcpy(m_pChars, str, m_size);
m_pChars[m_size] = '\0';
}
CMyString(CMyString const& other)
:m_size(other.m_size)
,m_pChars(new char[other.m_size + 1])
{
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
~CMyString()
{
delete [] m_pChars;
}
CMyString& operator=(CMyString const& other)
{
if (this != &other)
{
delete [] m_pChars; m_pChars = NULL;
m_size = other.m_size;
m_pChars = new char[other.m_size + 1];
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
return *this;
}
private:
char * m_pChars;
size_t m_size;
};
Код конструктора безопасен к
возникновению исключений
Код конструктора копирования
безопасен к возникновению
исключений
При выбросе исключения объект
станет destructibe, но целостность
объекта будет нарушена для его
последующего использования:
переменная m_size будет
содержать некорректную длину, а
m_pChars будет равен NULL
52.
class CMyString{
public:
CMyString(const char * str):m_size(strlen(str))
{
m_pChars = new char[m_size + 1];
memcpy(m_pChars, str, m_size);
m_pChars[m_size] = '\0';
}
Код конструктора безопасен к
возникновению исключений
CMyString(CMyString const& other)
:m_size(other.m_size)
,m_pChars(new char[other.m_size + 1])
{
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
~CMyString()
{
delete [] m_pChars;
}
CMyString& operator=(CMyString const& other)
{
if (this != &other)
{
char * pNewChars = new char[other.m_size + 1];
m_size = other.m_size;
delete [] m_pChars; m_pChars = pNewChars;
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
return *this;
}
private:
char * m_pChars;
size_t m_size;
};
Код конструктора копирования
безопасен к возникновению
исключений
При выбросе исключения не
происходит утечек памяти, а
объект остается в том же
состоянии, в каком он был до
вызова оператора =
Безопасность оператора
присваивания достигнута
53.
class CMyString{
public:
CMyString(const char * str):m_size(strlen(str))
{
m_pChars = new char[m_size + 1];
memcpy(m_pChars, str, m_size);
m_pChars[m_size] = '\0';
}
CMyString(CMyString const& other)
:m_size(other.m_size)
,m_pChars(new char[other.m_size + 1])
{
memcpy(m_pChars, other.m_pChars, m_size + 1);
}
~CMyString()
{
delete [] m_pChars;
}
CMyString& operator=(CMyString const& other)
{
if (this != &other)
{
CMyString copy(other);
std::swap(m_pChars, copy.m_pChars);
std::swap(m_size, copy.m_size);
}
return *this;
}
private:
char * m_pChars;
size_t m_size;
};
Код конструктора безопасен к
возникновению исключений
Код конструктора копирования
безопасен к возникновению
исключений
При выбросе исключения не
происходит утечек памяти, а
объект остается в том же
состоянии, в каком он был до
вызова оператора =, кроме того,
код оператора = стал более
понятным
Безопасность оператора
присваивания достигнута
54. Правило разработки exception-safe кода
Правило разработки exceptionsafe кодаВ каждом методе или функции
выделите код, который может
выбрасывать исключения
Реорганизуйте код так, чтобы
исключения не выбрасывались в
процессе изменения состояния
программы (или объекта)
Лишь после того, как задача
выполнена, можно изменять состояние
программы используя операции, не
55.
class CStringStack{
struct Item
{
Item(std::string const& str, Item * p)
:data(str),pNext(p)
{
}
std::string data;
Item * pNext;
};
public:
bool IsEmpty()const
{
return (m_pTop == NULL);
}
std::string Pop()
{
if (IsEmpty())
{
throw std::logic_error("Stack is empty");
}
std::string result = m_pTop->data;
Item * pItem = m_pTop;
m_pTop = m_pTop->pNext;
delete pItem;
return result;
}
private:
Item * m_pTop;
};
Код конструктора безопасен к
возникновению исключений
Создание копии строки может
привести к выбросу исключения
При этом вытолкнутый элемент
окажется безвозвратно потерян
– результат возвращен не будет,
а элемент из стека уже удален
56.
class CStringStack{
struct Item
{
Item(std::string const& str, Item * p)
:data(str),pNext(p)
{
}
std::string data;
Item * pNext;
};
public:
bool IsEmpty()const
{
return (m_pTop == NULL);
}
void Pop(std::string & result)
{
if (IsEmpty())
{
throw std::logic_error("Stack is empty");
}
result = m_pTop->data;
Item * pItem = m_pTop;
m_pTop = m_pTop->pNext;
delete pItem;
}
private:
Item * m_pTop;
};
Код конструктора безопасен к
возникновению исключений
Такое решение решает проблему,
однако фактически метод выполняет
две задачи:
•Выталкивает элемент с вершины
стека
•Возвращает вытолкнутое значение
При проектировании программных
систем следует стремиться к тому,
чтобы каждый модуль, класс и
функция имели единственную четко
заданную сферу ответственности
57.
class CStringStack{
struct Item
{
Item(std::string const& str, Item * p)
:data(str),pNext(p)
{
}
std::string data;
Item * pNext;
};
public:
bool IsEmpty()const
{
return (m_pTop == NULL);
}
void Pop()
{
if (IsEmpty())
throw std::logic_error("Stack is empty");
Item * pItem = m_pTop;
m_pTop = m_pTop->pNext;
delete pItem;
}
std::string GetTop()const
{
if (IsEmpty())
throw std::logic_error("Stack is empty");
return m_pTop->data;
}
private:
Item * m_pTop;
};
Код конструктора безопасен к
возникновению исключений
58. Безопасность исключений и вопросы проектирования
Как правило, небезопасность квозникновению исключений и плохое
проектирование программ идут рука
об руку
◦ Часто небезопасный к возникновению
исключений код может быть достаточно
легко исправлен
◦ Однако, если невозможность такого
исправления обусловлена архитектурой
кода, скорее всего код плохо
спроектирован
59. Гарантии безопасности исключений
Базовая гарантия безопасности◦ Скажи Нет! утечкам ресурсов
◦ Безопасное разрушение и использование
объекта
◦ Согласованное (не обязательно
предсказуемое) состояние объекта
Строгая гарантия безопасности
◦ Поддержка транзакционной семантики
выполнения методов «commit-or-rollback» объект не меняет своего состояния при
выбрасывании исключения
Гарантия отсутствия исключений
◦ Функция или метод ни при каких условиях не
выбрасывает исключений
60. Тонкая обработка системных исключений
Режим компиляции /EHa позволяет перехватывать иобрабатывать системные исключения, возникающие в
процессе работы программы. Однако обработчик
таких исключений помещается в блок catch (…) и не
дает возможности определить, какое именно
исключение возникло.
Для более детальной обработки системных
исключений можно воспользоваться механизмом
трансляции исключений
61. Трансляция исключений
Транслятор исключений – пользовательская callbackфункция, прототип которой имеет видvoid MyTranslator(unsigned err_code,
_EXCEPTION_POINTERS *p);
Параметр err_code обозначает тип исключительной
ситуации (константа
EXCEPTION_INT_DIVIDE_BY_ZERO, например,
обозначает попытку деления на ноль в целочисленной
арифметике, а константа
EXCEPTION_ACCESS_VIOLATION – попытку обратиться
к запрещенному адресу памяти).
Указатель p содержит адрес структуры, содержащей
дополнительную информацию об исключении.
62. Трансляция исключений (продолжение)
Написанный транслятор необходимо зарегистрироватьвызовом функции
_set_se_translator(MyTranslator);
После этого транслятор получает управление при
каждом выбросе системного исключения.
Транслятор – не обработчик исключения!
По завершению его работы выполняется стандартные
действия по обработке исключения!
63. Преобразование системных исключений в пользовательские
void MyTranslator(unsigned err_code,_EXCEPTION_POINTERS *p) {
throw err_code;
}
Теперь в блоке catch(unsigned) можно выполнить более
тонкую обработку системных исключений:
int main() {
int x = 0;
int *px = NULL;
_set_se_translator(MyTranslator);
try {
//
cout << 2/x;
*px=0;
}
64. Преобразование системных исключений в пользовательские (продолжение)
catch (unsigned e) {switch (e) {
case EXCEPTION_INT_DIVIDE_BY_ZERO:
cout << "Division by zero" << endl;
break;
case EXCEPTION_ACCESS_VIOLATION:
cout << "Invalid pointer assignement" << endl;
break;
}
}
return 0;
}
programming