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


Исключительные ситуации

Содержание

Обработка ошибок и непредвиденных ситуацийВ процессе работы программы возможно возникновение непредвиденных ситуацийНехватка памяти и других системных ресурсовОшибки ввода-выводаНекорректные данные, поступившие от пользователяНарушение целостности данных (поврежден файл с данными)Некорректные параметры функцийХорошо спроектированная

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

Слайд 1Исключительные ситуации

Исключительные ситуации

Слайд 2Обработка ошибок и непредвиденных ситуаций
В процессе работы программы возможно возникновение

непредвиденных ситуаций
Нехватка памяти и других системных ресурсов
Ошибки ввода-вывода
Некорректные данные, поступившие

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

Слайд 3Обнаружение ошибочных ситуаций
Проверяйте данные поступающие из внешних источников на корректность
Файлы,

введенные пользователем данные, сетевые пакеты и т.п.
Осуществляйте проверку успешности вызовов

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

Слайд 4Способы обработки ошибок
Проигнорировать ошибку, оставив программу в неопределенном состоянии
Самых худший

вариант – никогда так не делайте!
Вывод сообщения об ошибке и

аварийное завершение работы программы
Немногим лучше предыдущего
Поместить код ошибки в глобальную переменную
Проблемы с многопоточными приложениями
Предусмотреть специальное значение функции, сигнализирующее об ошибке
А как возвращать нормальное значение?
Вызвать функцию-обработчик ошибки
Часто необходимо передавать контекст возникновения ошибки
Необходимо восстанавливать нормальное выполнение
Воспользоваться механизмом исключений языка C++
Способы обработки ошибокПроигнорировать ошибку, оставив программу в неопределенном состоянииСамых худший вариант – никогда так не делайте!Вывод сообщения

Слайд 5Механизм исключений
Встроенное в язык C++ средство для обработки внештатных ситуаций

во время выполнения программы
Исключения позволяют программе обработать внештатную ситуацию на

более высоком уровне, на котором возможно восстановить нормальную работу программы
Обработка исключений осуществляется кодом вне обычного потока выполнения
Механизм исключенийВстроенное в язык C++ средство для обработки внештатных ситуаций во время выполнения программыИсключения позволяют программе обработать

Слайд 6Оператор try-catch
Синтаксис
try { код, в котором возможно генерирование исключений } catch(объявление исключения) { код, обрабатывающий исключение } [catch

(…) { код, обрабатывающий исключения любого типа }]

Оператор try-catchСинтаксисtry { 	код, в котором возможно генерирование исключений } catch(объявление исключения) { 	код, обрабатывающий исключение }

Слайд 7Оператор throw
Синтаксис:
throw [выражение]
Выражение может быть любого типа (кроме void)
При выполнении

данного оператора
создается объект исключительной ситуации на основе объекта, выступающего в

качестве аргумента оператора throw
Дальнейшее выполнение программы прерывается, происходит поиск подходящего обработчика в защищенном блоках try-catch
Если подходящий обработчик найден, то происходит раскрутка стека (stack unwinding), при которой разрушаются все автоматические объекты, созданные между началом соответствующего блока try
Если обработчик не найден, происходит завершение работы программы
Оператор throwСинтаксис:throw [выражение]Выражение может быть любого типа (кроме void)При выполнении данного операторасоздается объект исключительной ситуации на основе

Слайд 8Классы исключений
Использование классов в качестве типа объектов исключений имеет ряд

преимуществ
Возможность хранения подробной информации об исключении
Возможность использования полиморфизма
Оператор catch ловит

исключения не только указанного типа, но и всех производных от него типов:
try { throw CDerivedException; } catch (CBaseException const& e) { }
Классы исключенийИспользование классов в качестве типа объектов исключений имеет ряд преимуществВозможность хранения подробной информации об исключенииВозможность использования

Слайд 9Выбрасывание и перехват исключений в C++
Исключения всегда выбрасываются «по значению»
У

классов исключений должен быть доступен конструктор копирования
Перехват исключений должен происходить

по ссылке
В противном случае может произойти «урезание» информации об исключении
Выбрасывание и перехват исключений в C++Исключения всегда выбрасываются «по значению»У классов исключений должен быть доступен конструктор копированияПерехват

Слайд 10#include
#include
#include
#include

double MySqrt(double arg)
{
if (arg < 0)
{
throw

std::invalid_argument("the argument must be >= 0");
}

return sqrt(arg);
}

int main()
{
try
{
std::cout

= " << MySqrt(3) << "\n";
std::cout << "sqrt(-1) = " << MySqrt(-1) << "\n";
}
catch (std::invalid_argument const & e)
{
std::cout << "Error: " << e.what() << "\n";
}

return 0;
}

Output:
sqrt(3) = 1.732051
Error: argument must be >= 0


Слайд 11Перевыброс исключения
Перехватив исключение в блоке catch можно перевыбросить его снова,

чтобы оно было перехвачено внешним обработчиком
Синтаксис:
throw;
Пример:
try { ... } catch(SomeError const& e) {

//... throw; }
Перевыброс исключенияПерехватив исключение в блоке catch можно перевыбросить его снова, чтобы оно было перехвачено внешним обработчикомСинтаксис:throw;Пример:try {

Слайд 12Стандартные классы исключений библиотеки STL

Стандартные классы исключений библиотеки STL

Слайд 13Основные классы исключений STL
exception – базовый класс для всех исключений,

выбрасываемых кодом библиотеки
logic_error – базовый класс для ошибок, которые можно

было бы выявить до выполнения программы
runtime_error – базовый класс ошибок, которые, как правило, можно выявить только во время работы программы
bad_alloc – ошибка выделения памяти
bad_cast – ошибка приведения типа
Основные классы исключений STLexception – базовый класс для всех исключений, выбрасываемых кодом библиотекиlogic_error – базовый класс для

Слайд 14Преимущества использования исключений
Реакция на исключение происходит всегда
Коды ошибок работают только

тогда, когда их проверяют
Возможность различной реакции на различные типы исключений
Объекты,

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

Слайд 15Проблемы
При использовании исключений необходимо иметь представление о том, какие исключения

могут быть выброшены в результате работы функции или метода класса
Увеличение

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

Слайд 16Выброс исключения в конструкторе
При выбросе исключения в теле конструктора или

в списке инициализации процесс конструирования экземпляра класса прерывается и он

считается не созданным
Деструктор для такого класса вызван не будет
Будут вызваны деструкторы для тех полей класса, для которых успели выполниться конструкторы
Порядок вызова конструкторов полей класса совпадает с порядком их перечисления в объявлении класса
Порядок вызова деструкторов – обратный порядку вызова конструкторов
Выброс исключения в конструктореПри выбросе исключения в теле конструктора или в списке инициализации процесс конструирования экземпляра класса

Слайд 17class A
{
public:
A(std::string const& name)
:m_name(name)
{
std::cout

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;
};

int main()
{
try
{
B b2("Test", 1000000000);
}
catch (std::bad_alloc const & e)
{
std::cout << "Error: " << e.what() << "\n";
}

return 0;
}

Output:
A::A(Test)
A::~A(Test)
Error: bad allocation

Нехватка памяти и выброс исключения std::bad_alloc

class A{public:	A(std::string const& name)		:m_name(name)			{		std::cout

Слайд 18Выброс исключений в деструкторе
Не допускайте выброса исключений в деструкторах объектов
В

C++ выброс исключения в деструкторе приводит к аварийному завершению работы

программы
Выброс исключений в деструктореНе допускайте выброса исключений в деструкторах объектовВ C++ выброс исключения в деструкторе приводит к

Слайд 19Exception-safe programming
Разработка кода, безопасного к возникновению исключений

Exception-safe programmingРазработка кода, безопасного к возникновению исключений

Слайд 20Код, устойчивый к возникновению исключений
Объект, как минимум, должен оставаться destructible

– последующий вызов деструктора данного объекта не должен приводить к

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

Код, устойчивый к возникновению исключенийОбъект, как минимум, должен оставаться destructible – последующий вызов деструктора данного объекта не

Слайд 21class 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.

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

Слайд 22class 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

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

Слайд 23class 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;
};

Код конструктора безопасен к возникновению исключений

Код конструктора копирования безопасен к возникновению исключений

При выбросе исключения не происходит утечек памяти, а объект остается в том же состоянии, в каком он был до вызова оператора =
Безопасность оператора присваивания достигнута

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

Слайд 24class 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;
};

Код конструктора безопасен к возникновению исключений

Код конструктора копирования безопасен к возникновению исключений

При выбросе исключения не происходит утечек памяти, а объект остается в том же состоянии, в каком он был до вызова оператора =, кроме того, код оператора = стал более понятным
Безопасность оператора присваивания достигнута

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

Слайд 25Правило разработки exception-safe кода
В каждом методе или функции выделите код,

который может выбрасывать исключения
Реорганизуйте код так, чтобы исключения не выбрасывались

в процессе изменения состояния программы (или объекта)
Лишь после того, как задача выполнена, можно изменять состояние программы используя операции, не выбрасывающие исключения
Правило разработки exception-safe кодаВ каждом методе или функции выделите код, который может выбрасывать исключенияРеорганизуйте код так, чтобы

Слайд 26class 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;
};

Код конструктора безопасен к возникновению исключений

Создание копии строки может привести к выбросу исключения
При этом вытолкнутый элемент окажется безвозвратно потерян – результат возвращен не будет, а элемент из стека уже удален


Слайд 27class 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;
};

Код конструктора безопасен к возникновению исключений

Такое решение решает проблему, однако фактически метод выполняет две задачи:
Выталкивает элемент с вершины стека
Возвращает вытолкнутое значение

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


Слайд 28class 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;
};

Код конструктора безопасен к возникновению исключений


Слайд 29Безопасность исключений и вопросы проектирования
Как правило, небезопасность к возникновению исключений

и плохое проектирование программ идут рука об руку
Часто небезопасный к

возникновению исключений код может быть достаточно легко исправлен
Однако, если невозможность такого исправления обусловлена архитектурой кода, скорее всего код плохо спроектирован
Безопасность исключений и вопросы проектированияКак правило, небезопасность к возникновению исключений и плохое проектирование программ идут рука об

Слайд 30Гарантии безопасности исключений
Базовая гарантия безопасности
Скажи Нет! утечкам ресурсов
Безопасное разрушение и

использование объекта
Согласованное (не обязательно предсказуемое) состояние объекта
Строгая гарантия безопасности
Поддержка транзакционной

семантики выполнения методов «commit-or-rollback» - объект не меняет своего состояния при выбрасывании исключения
Гарантия отсутствия исключений
Функция или метод ни при каких условиях не выбрасывает исключений
Обязательное требование для деструкторов и ряда вспомогательных функций типа swap
Гарантии безопасности исключенийБазовая гарантия безопасностиСкажи Нет! утечкам ресурсовБезопасное разрушение и использование объектаСогласованное (не обязательно предсказуемое) состояние объектаСтрогая

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

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

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

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

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


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

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