Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
для шпор(печатаем 8 стр на листе).docx
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
2.86 Mб
Скачать

Вопрос 23

Концепции исключений:

    1. Обнаружение ошибок и порождение исключений

    2. Перехват ошибки и выполнение ответных действий

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

Синтаксис порождения и перехвата исключений

If (divisor ==0) throw int();

Try

{

float amgle=math (…);

}

В операторных скобках {} контролируемый блок начинается со слова try, далее блок исключения:

catch (int)

{

}

Раскрутка стека

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

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

24. Группировка и композиция исключений. Повторная генерация. Перехват всех исключений.

В стандартной библиотеке есть базовый класс исключений std: exeption

Повторная генерация

25. Автоматическое управление ресурсами. Методика raii.

Принцип "выделение ресурса есть инициализация" удобно использовать при выделении любого типа ресурсов. Это позволяет сделать работу программы более надежной. Использование этого принципа особенно важно, если в ходе работы приложения могут возникать исключительные ситуации. В этом случае сложно заранее предусмотреть, в какой именно момент возникнет исключение и какие необходимые действия не будут совершены в результате преждевременного завершения программы. Например, если приложение открывает какой-нибудь файл или выделяет блок памяти, то при завершении работы приложения желательно соответственно закрыть файл или освободить выделенный блок памяти. Однако исключение может быть сгенерировано еще до того, как будет выполнена инструкция, закрывающая файл или освобождающая блок памяти. В результате эта инструкция так и не будет выполнена: 

void f() { FILE* pf; if ((pf = fopen("myfile.txt", "rt")) == NULL) { //не удалось открыть файл exit(1); } //здесь выполняем нужную работу с файлом //и здесь может возникнуть какое-нибудь исключение //... //если исключение возникнет, то до этой строки мы не доберемся //и файл не будет закрыт fclose(pf); } Если подобных ситуаций необходимо избегать, то лучше организовать работу с файлом, соблюдая принцип "выделение ресурса есть инициализация". Для этого можно создать класс, конструктор которого будет открывать файл, а в деструкторе файл будет закрываться. При начале работы с файлом пользователь должен создать объект этого класса. При этом файл будет автоматически открыт конструктором класса.  В случае генерации исключения при работе приложения объект будет уничтожен и при этом неизбежно будет вызван его деструктор, который и закроет файл. Если исключение не будет сгенерировано и работа программы завершится нормально, то и в этом случае пользователю не придется заботится о явном закрытии файла, так как созданный им объект будет автоматически уничтожен при выходе из области видимости и файл будет закрыт деструктором класса. class FileOpen { FILE* pf; public: FileOpen(char* filename, char* mode) { if ((pf = fopen(filename, mode)) == NULL) { //вывести сообщение о том, что файл открыть //не удалось } } ~FileOpen() { fclose(pf); } //... };