Главная » Просмотр файлов » Б. Страуструп - Язык программирования С++

Б. Страуструп - Язык программирования С++ (1119446), страница 65

Файл №1119446 Б. Страуструп - Язык программирования С++ (Б. Страуструп - Язык программирования С++) 65 страницаБ. Страуструп - Язык программирования С++ (1119446) страница 652019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 65)

Поэтому можно было написать так:int add(int x, int y)// сложить x и y с контролем{if (x > 0 && y > 0 && x > MAXINT - y|| x < 0 && y < 0 && x < MININT + y)throw Int_overflow("+", x, y);// Сюда мы попадаем, либо когда проверка// на переполнение дала отрицательный результат,// либо когда x и y имеют разные знакиreturn x + y;}void f(){try {add(1,2);add(MAXINT,-2);add(MAXINT,2);}catch (Matherr& m) {// ...m.debug_print();}}// а дальше - переполнениеЗдесь последнее обращение к add приведет к запуску особой ситуации, который, в свою очередь,приведет к вызову Int_overflow::debug_print().Если бы особая ситуация передавалась по значению, а не241Бьерн Страуструп.Язык программирования С++по ссылке, то была бы вызвана функция Matherr::debug_print().Нередко бывает так, что перехватив особую ситуацию, обработчик решает, что с этой ошибкой онничего не сможет поделать.

В таком случае самое естественное запустить особую ситуацию снова внадежде, что с ней сумеет разобраться другой обработчик:void h(){try {// какие-то операторы}catch (Matherr) {if (can_handle_it) {// сделать ее}else {throw;// особой ситуации}}}// если обработка возможна,// повторный запуск перехваченнойПовторный запуск записывается как оператор throw без параметров. При этом снова запускаетсяисходная особая ситуация, которая была перехвачена, а не та ее часть, на которую рассчитанобработчик Matherr. Иными словами, если была запущена Int_overflow, вызывающая h() функция моглабы перехватить ее как Int_overflow, несмотря на то, что она была перехвачена в h() как Matherr изапущена снова:void k(){try {h();// ...}catch (Int_overflow) {// ...}}Полезен вырожденный случай перезапуска.

Как и для функций, эллипсис ... для обработчика означает"любой параметр", поэтому оператор catch (...) означает перехват любой особой ситуации:void m(){try {// какие-то операторы}catch (...) {// привести все в порядокthrow;}}Этот пример надо понимать так: если при выполнении основной части m() возникает особая ситуация,выполняется обработчик, которые выполняет общие действия по устранению последствий особойситуации, после этих действий особая ситуация, вызвавшая их, запускается повторно.Поскольку обработчик может перехватить производные особые ситуации нескольких типов, порядок, вкотором идут обработчики в проверяемом блоке, существенен.

Обработчики пытаются перехватитьособую ситуацию в порядке их описания. Приведем пример:try {// ...242Бьерн Страуструп.}catch (ibuf) {// обработка}catch (io) {// обработка}catch (stdlib)// обработка}catch (...) {// обработка}Язык программирования С++переполнения буфера вводалюбой ошибки ввода-вывода{любой особой ситуации в библиотекевсех остальных особых ситуацийТип особой ситуации в обработчике соответствует типу запущенной особой ситуации в следующихслучаях: если эти типы совпадают, или второй тип является типом доступного базового классазапущенной ситуации, или он является указателем на такой класс, а тип ожидаемой ситуации тожеуказатель ($$R.4.6).Поскольку транслятору известна иерархия классов, он способен обнаружить такие нелепые ошибки,когда обработчик catch (...) указан не последним, или когда обработчик ситуации базового классапредшествует обработчику производной от этого класса ситуации ($$R15.4).

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

Например:void use_file(const char* fn){FILE* f = fopen(fn,"w");fclose(f);}// работаем с fВсе это выглядит вполне нормально до тех пор, пока вы не поймете, что при любой ошибке,происшедшей после вызова fopen() и до вызова fclose(), возникнет особая ситуация, в результатекоторой мы выйдем из use_file(), не обращаясь к fclose(). Стоит сказать, что та же проблема возникает ив языках, не поддерживающих особые ситуации. Так, обращение к функции longjump()из стандартнойбиблиотеки С может иметь такие же неприятные последствия.Если вы создаете устойчивую к ошибкам системам, эту проблему придется решать. Можно датьпримитивное решение:void use_file(const char* fn){FILE* f = fopen(fn,"w");try {// работаем с f}catch (...) {fclose(f);throw;}fclose(f);}Вся часть функции, работающая с файлом f, помещена в проверяемый блок, в котором243Бьерн Страуструп.Язык программирования С++перехватываются все особые ситуации, закрывается файл и особая ситуация запускается повторно.Недостаток этого решения в его многословности, громоздкости и потенциальной расточительности.

Ктому же всякое многословное и громоздкое решение чревато ошибками, хотя бы в силу усталостипрограммиста. К счастью, есть более приемлемое решение. В общем виде проблему можносформулировать так:void{//////////////}acquire()запрос ресурса 1...запрос ресурса nиспользование ресурсовосвобождение ресурса n...освобождение ресурса 1Как правило бывает важно, чтобы ресурсы освобождались в обратном по сравнению с запросамипорядке. Это очень сильно напоминает порядок работы с локальными объектами, создаваемымиконструкторами и уничтожаемыми деструкторами.

Поэтому мы можем решить проблему запроса иосвобождения ресурсов, если будем использовать подходящие объекты классов с конструкторами идеструкторами. Например, можно определить класс FilePtr, который выступает как тип FILE* :class FilePtr {FILE* p;public:FilePtr(const char* n, const char* a){ p = fopen(n,a); }FilePtr(FILE* pp) { p = pp; }~FilePtr() { fclose(p); }operator FILE*() { return p; }};Построить объект FilePtr можно либо, имея объект типа FILE*, либо, получив нужные для fopen()параметры. В любом случае этот объект будет уничтожен при выходе из его области видимости, и егодеструктор закроет файл.

Теперь наш пример сжимается до такой функции:void use_file(const char* fn){FilePtr f(fn,"w");// работаем с f}Деструктор будет вызываться независимо от того, закончилась ли функция нормально, или произошелзапуск особой ситуации.9.4.1 Конструкторы и деструкторыОписанный способ управления ресурсами обычно называют "запрос ресурсов путем инициализации".Это универсальный прием, рассчитанный на свойства конструкторов и деструкторов и ихвзаимодействие с механизмом особых ситуаций.Объект не считается построенным, пока не завершил выполнение его конструктор.

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

Для простых конструкторов было бы идеально всегдаудовлетворять хотя бы одному условию - правильности или законченности объектов, и никогда неоставлять объект в "наполовину построенном" состоянии. Этого можно добиться, если применять припостроении членов способ "запроса ресурсов путем инициализации".244Бьерн Страуструп.Язык программирования С++Рассмотрим класс X, конструктору которого требуется два ресурса: файл x и замок y (т.е. монопольныеправа доступа к чему-либо). Эти запросы могут быть отклонены и привести к запуску особой ситуации.Чтобы не усложнять работу программиста, можно потребовать, чтобы конструктор класса X никогда незавершался тем, что запрос на файл удовлетворен, а на замок нет. Для представления двух видовресурсов мы будем использовать объекты двух классов FilePtr и LockPtr (естественно, было быдостаточно одного класса, если x и y ресурсы одного вида).

Запрос ресурса выглядит какинициализация представляющего ресурс объекта:class X {FilePtr aa;LockPtr bb;// ...X(const char* x, const char* y): aa(x),bb(y){ }// ...};// запрос `x'// запрос `y'Теперь, как это было для случая локальных объектов, всю служебную работу, связанную с ресурсами,можно возложить на реализацию. Пользователь не обязан следить за ходом такой работой.

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

Список файлов книги

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