LEC_cpp5 (1119520)

Файл №1119520 LEC_cpp5 (Лекции Волковой 2009)LEC_cpp5 (1119520)2019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла

6 лекция - C++ (5).

Средства обработки ошибок. Исключения в С++.

Аппарат обработки ошибок позволяет достаточно эффективно писать надежные, безотказные программы, которые не "падают" при возникновении ошибочной ситуации в программе (например, не удалось открыть файл, встретился недопустимый символ), а разумно на нее реагируют (например, выдают соответствующую диагностику, предлагают повторить ввод неверно набранной строки) и нормально завершаются.

Обработка исключительных ситуаций в С++ организуется с помощью ключевых слов try, catch и throw.

Инструкции программы, при выполнении которых необходимо обеспечить обработку исключительных ситуаций, выделяются в try-catch -блок.

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

Основные формы инструкций try, catch и throw:

try {

….. throw исключительная_ситуация; …..

}

catch (type) {---/*throw;*/}

catch (type arg) {---/*throw;*/}

catch (…) {---/*throw;*/}

Инструкции try могут быть вложенными.

Параметром оператора throw является исключительная ситуация - объект некоторого типа, в частности, встроенного. Сгенерированная исключительная ситуация перехватывается обработчиком catch.

Если обработчики текущего try-блока не могут обработать ошибку или могут обработать ее лишь частично, внутри оператора catch допускается обращение к оператора throw без параметров, что означает передачу обрабатываемой исключительной ситуации объемлющему try-блоку.

Перехват исключений.

С каждым try-блоком может быть связано несколько операторов catch. Они просматриваются по очереди сверху вниз, и, вообще говоря, порядок задания орераторов catch существен.

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

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

Существует специальный вид обработчика, перехватывающего любые исключительные ситуации - catch (…){---}. Естественно, он должен находиться в конце последовательности операторов catch.

Если для сгенерированной исключительной ситуации в ближайшем try-блоке нет подходящего обработчика, она перехватывается объемлющим try-блоком (main()®f()®g()®h()). Если же подходящего обработчика так и не удалось найти, может произойти ненормальное завершение программы. При этом вызывается стандартная библиотечная функция terminate (), которая в свою очередь вызывает функцию abort (), чего лучше избегать.

Пример:

class A {

public:

A () {cout << “Constructor of A\n”;}

~A () {cout << “Destructor of A\n”;}

};

class Error {};

class Error_of_A : public Error {};

void f () {

A a;

throw 1;

cout << “This message is never printed” << endl;

}

int main () {

try {

f ();

throw Error_of_A();

}

catch (int) {cerr << “Catch of int\n”;}

catch (Error_of_A) {cerr << “Catch of Error_of_A \n”;}

catch (Error) {cerr << “Catch of Error\n”;}

return 0;

}

Результат будет следующий:

Constructor of A

Destructor of A // т.к. в f обработчика нет, поиск идет дальше, но при выходе

из f вызывается деструктор локальных объектов.

Catch of int

Если поменять строки внутри try, получим:

Catch of Error_of_A

Если закомментировать строку

// catch (Error_of_A){cerr << “Catch of Error_of_A \n”;}, получим

Catch of Error

В реальных программах удобно вводить классы исключений и создавать иерархию исключений. Например,

class MathEr {...virtual void ErrProcess();...};

class Overflow : public Math Er {... void ErrProcess();...};

class ZeroDivide : public Math Er {... void ErrProcess();...};

...

Через параметры конструктора исключения можно передавать для последующей обработки любую нужную информацию. А если использовать виртуальные функции, можно после try-блока задать единственный обработчик catch, перехватывающий объект базового класса, но обрабатывающего любые исключения:

try { ...

}

catch (MathEr& m) {... m. ErrProcess(); ...}

Организованная таким образом обработка исключений позволяет легко модифицировать программы.

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

тип_рез имя_функции (список_арг) [const] throw (список_типов)

Если список типов пустой, то функция не может генерировать никаких исключений.

Если же функция все-таки сгенерировала недекларированное исключение, вызывается библиотечная функция unexpected (); работающая аналогично функции terminate(); (если не определена своя реакция на это событие), но, естественно, с другой диагностикой.

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

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

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

  • При генерации исключения (throw X) создается временный объект - копия X (работает конструктор копирования). С этой копией будет работать выбранный далее обработчик; она существует до тех пор, пока обработка исключения не будет завершена.

  • Для всех других объектов try-блока, созданных к этому моменту, перед выходом из try-блока освобождается память; при этом для объектов – экземпляров классов вызывается деструктор. Это же делается и для уже созданных подобъектов: членов класса – объектов другого класса и баз. Этот процесс называют «раскруткой» («сверткой») стека.

  • Если в списке обработчиков этого try-блока найден подходящий, то выполняются операторы этого catch; затем выполнение программы продолжается с оператора, расположенного за последним обработчиком этого try-блока.

  • Если в списке данного try-блока не нашлось подходящего обработчика, то поиск продолжается в динамически объемлющих try-блоках (при этом процесс свертки стека продолжается).

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

Динамическая информация о типе.

Одним из крупных расширений С является автоматическая идентификация типа во время исполнения, или RTTI (Run-Time Type Identification). Для использования RTTI в программу следует включить заголовок <typeinfo>.

Механизм RTTI состоит из трех частей:

  1. оператор dynamic_cast в основном предназначен для получения указателя на объект производного класса при наличии указателя на базовый класс этого объекта;

  2. оператор typeid для идентификации точного типа объекта при наличии указателя на базовый класс;

  3. структура type_info, позволяющая получить дополнительную информацию, ассоциированную с типом.

(1) Оператор dynamic_cast реализует приведение типов (указателей или ссылок) полиморфных классов в динамическом режиме (кроме того, в С++ добавлены другие операторы приведения типов: const_cast, reinterpret_cast и static_cast, не имеющие отношения к RTTI, и в курсе мы их рассматривать не будем).

Основная форма оператора dynamic_cast:

dynamic_cast < целевой тип > ( выражение )

Если даны два полиморфных класса B и D (причем D – производный от B), то dynamic_cast всегда может привести D* к B*. Также dynamic_cast может привести B* к D*, но только в том случае, если объект, на который указывает указатель, действительно является объектом типа D (либо производным от него)!

При неудачной попытке приведения типов результатом выполнения dynamic_cast является 0, если в операторе использовались указатели. Если же использовались ссылки, генерируется исключительная ситуация bad_cast.

Пример:

Base *bp, b_ob;

Derived *dp, d_ob;

bp = &d_ob;

dp = dynamic_cast <Derived *> (bp);

if (dp) cout << «Приведение типов прошло успешно»;

bp = &b_ob;

dp = dynamic_cast <Derived *> (bp);

if (!dp) cout << «Приведения типов не произошло»;

(2)-(3) Информацию о типе объекта можно получить с помощью оператора typeid.

Основная форма оператора typeid:

typeid (выражение)

Оператор typeid возвращает ссылку на объект типа type_info, представляющий тип объекта, обозначенного этим выражением.

В классе type_info определены следующие открытые члены:

bool operator == (const type_info & объект); //для сравнения типов

bool operator != (const type_info & объект); //для сравнения типов

bool before (const type_info & объект); //для внутреннего использования

const char * name (); //возвращает указатель на имя типа

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

typeid часто применяется к разыменованным указателям (typeid (*р)). Если указатель р==0, то будет сгенерирована исключительная ситуация bad_typeid.

Другая форма оператора typeid:

typeid (имя_типа)

В этом случае оператор typeid возвращает ссылку на объект типа type_info, представляющий тип именно с этим именем. Пример:

class Base {

virtual void f () {...};

};

class Derived1: public Base { ...

};

class Derived2: public Base { ...

};

int main () {

int i;

Base *p, b_ob;

Derived1 ob1;

Derived2 ob2;

cout << «Тип i - » << typeid (i).name () << endl;

p = &b_ob;

cout << “p указывает на объект типа ” << typeid (*p).name () << endl;

p = &ob1;

cout << “p указывает на объект типа ” << typeid (*p).name () << endl;

p = &ob2;

cout << “p указывает на объект типа ” << typeid (*p).name () << endl;

if ( typeid (ob1) == typeid (ob2) )

cout << “Тип объектов ob1 и ob2 одинаков\n”;

else

cout << “Тип объектов ob1 и ob2 не одинаков\n”;

return 0;

}

6


Характеристики

Тип файла
Документ
Размер
80,5 Kb
Тип материала
Высшее учебное заведение

Тип файла документ

Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.

Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.

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

Список файлов лекций

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6374
Авторов
на СтудИзбе
309
Средний доход
с одного платного файла
Обучение Подробнее