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

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

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

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

Например,если после построения aa и до построения bb возникнет особая ситуация, то будет вызван толькодеструктор aa, но не bb.Это означает, что если строго придерживаться этой простой схемы запроса ресурсов, то все будет впорядке. Еще более важно то, что создателю конструктора не нужно самому писать обработчики особыхситуаций.Для требований выделить блок в свободной памяти характерен самый произвольный порядок запросаресурсов. Примеры таких запросов уже неоднократно встречались в этой книге:class X {int* p;// ...public:X(int s) { p = new int[s]; init(); }~X() { delete[] p; }// ...};Это типичный пример использования свободной памяти, но в совокупности с особыми ситуациями онможет привести к ее исчерпанию памяти. Действительно, если в init() запущена особая ситуация, тоотведенная память не будет освобождена.

Деструктор не будет вызываться, поскольку построениеобъекта не было завершено. Есть более надежный вариант этого примера:template<class T> class MemPtr {public:T* p;MemPtr(size_t s) { p = new T[s]; }~MemPtr() { delete[] p; }operator T*() { return p; }}class X {MemPtr<int> cp;// ...public:X(int s):cp(s) { init(); }// ...};Теперь уничтожение массива, на который указывает p, происходит неявно в MemPtr.

Если init() запуститособую ситуацию, отведенная память будет освобождена при неявном вызове деструктора для245Бьерн Страуструп.Язык программирования С++полностью построенного вложенного объекта cp.Отметим также, что стандартная стратегия выделения памяти в С++ гарантирует, что если функцииoperator new() не удалось выделить память для объекта, то конструктор для него никогда не будетвызываться. Это означает, что пользователю не надо опасаться, что конструктор или деструктор можетбыть вызван для несуществующего объекта.Теоретически дополнительные расходы, требующиеся для обработки особых ситуаций, когда на самомделе ни одна из них не возникла, могут быть сведены к нулю. Однако, вряд ли это верно для раннихреализациях языка.

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

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

Метод "запросаресурсов путем инициализации" в совокупности с особыми ситуациями, сигнализирующими об ошибке,может пригодиться при создании многих библиотек.9.4.3 Исчерпание ресурсаЕсть одна из вечных проблем программирования: что делать, если не удалось удовлетворить запрос наресурс? Например, в предыдущем примере мы спокойно открывали с помощью fopen() файлы изапрашивали с помощью операции new блок свободной памяти, не задумываясь при этом, что такогофайла может не быть, а свободная память может исчерпаться. Для решения такого рода проблем упрограммистов есть два способа:1.Повторный запрос: пользователь должен изменить свой запрос и повторить его.2.Завершение: запросить дополнительные ресурсы от системы, если их нет, запустить особуюситуацию.Первый способ предполагает для задания приемлемого запроса содействие пользователя, во второмпользователь должен быть готов правильно отреагировать на отказ в выделении ресурсов.

Вбольшинстве случаев последний способ намного проще и позволяет поддерживать в системеразделение различных уровней абстракции.В С++ первый способ поддержан механизмом вызова функций, а второй - механизмом особыхситуаций. Оба способа можно продемонстрировать на примере реализации и использования операцииnew:#include <stdlib.h>extern void* _last_allocation;extern void* operator new(size_t size){void* p;while ( (p=malloc(size))==0 ) {if (_new_handler)(*_new_handler)(); // обратимся за помощьюelsereturn 0;}246Бьерн Страуструп.Язык программирования С++return _last_allocation=p;}Если операция new() не может найти свободной памяти, она обращается к управляющей функции_new_handler().

Если в _new_handler() можно выделить достаточный объем памяти, все нормально.Если нет, из управляющей функции нельзя возвратиться в операцию new, т.к. возникнет бесконечныйцикл. Поэтому управляющая функция может запустить особую ситуацию и предоставить исправлятьположение программе, обратившейся к new:void my_new_handler(){try_find_some_memory();if (found_some()) return;throw Memory_exhausted();//////////попытаемся найтисвободную памятьесли она найдена, все в порядкеиначе запускаем особуюситуацию "Исчерпание_памяти"}Где-то в программе должен быть проверяемый блок с соответствующим обработчиком:try {// ...}catch (Memory_exhausted) {// ...}В функции operator new() использовался указатель на управляющую функцию _new_handler, которыйнастраивается стандартной функцией set_new_handler().

Если нужно настроиться на собственнуюуправляющую функцию, надо обратиться такset_new_handler(&my_new_handler);Перехватить ситуацию Memory_exhausted можно следующим образом:void (*oldnh)() = set_new_handler(&my_new_handler);try {// ...}catch (Memory_exhausted) {// ...}catch (...) {set_new_handler(oldnh);// восстановить указатель на// управляющую функциюthrow();// повторный запуск особой ситуации}set_new_handler(oldnh);// восстановить указатель на// управляющую функциюМожно поступить еще лучше, если к управляющей функции применить описанный в $$9.4 метод"запроса ресурсов путем инициализации" и убрать обработчик catch (...).В решении, использующим my_new_handler(), от точки обнаружения ошибки до функции, в которой онаобрабатывается, не передается никакой информации. Если нужно передать какие-то данные, топользователь может включить свою управляющую функцию в класс.

Тогда в функции, обнаружившейошибку, нужные данные можно поместить в объект этого класса. Подобный способ, использующийобъекты-функции, применялся в $$10.4.2 для реализации манипуляторов. Способ, в которомиспользуется указатель на функцию или объект-функция для того, чтобы из управляющей функции,обслуживающей некоторый ресурс, произвести "обратный вызов" функции запросившей этот ресурс,обычно называется просто обратным вызовом (callback).При этом нужно понимать, что чем больше информации передается из обнаружившей ошибку функции247Бьерн Страуструп.Язык программирования С++в функцию, пытающуюся ее исправить, тем больше зависимость между этими двумя функциями.

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

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

Посколькуконструктор не возвращает такое значение, которое могла бы проверить вызывающая функция, естьследующие обычные (т.е. не использующие особые ситуации) способы сигнализации:[1]Возвратить объект в ненормальном состоянии в расчете, что пользователь проверит егосостояние.[2]Установить значение нелокальной переменной, которое сигнализирует, что создать объект неудалось.Особые ситуации позволяют тот факт, что создать объект не удалось, передать из конструктора вовне:Vector::Vector(int size){if (sz<0 || max<sz) throw Size();// ...}В функции, создающей вектора, можно перехватить ошибки, вызванные недопустимым размером(Size()) и попытаться на них отреагировать:Vector* f(int i){Vector* p;try {p = new Vector v(i);}catch (Vector::Size) {// реакция на недопустимый размер вектора}// ...return p;}Управляющая созданием вектора функция способна правильно отреагировать на ошибку.

В самомобработчике особой ситуации можно применить какой-нибудь из стандартных способов диагностики ивосстановления после ошибки. При каждом перехвате особой ситуации в управляющей функции можетбыть свой взгляд на причину ошибки. Если с каждой особой ситуацией передаются описывающие ееданные, то объем данных, которые нужно анализировать для каждой ошибки, растет. Основная задачаобработки ошибок в том, чтобы обеспечить надежный и удобный способ передачи данных от исходнойточки обнаружения ошибки до того места, где после нее возможно осмысленное восстановление.Способ "запроса ресурсов путем инициализации" - самый надежное и красивое решение в том случае,когда имеются конструкторы, требующие более одного ресурса. По сути он позволяет свести задачувыделения нескольких ресурсов к повторно применяемому, более простому, способу, рассчитанному наодин ресурс.248Бьерн Страуструп.Язык программирования С++9.5 Особые ситуации могут не быть ошибкамиЕсли особая ситуация ожидалась, была перехвачена и не оказала плохого воздействия на ходпрограммы, то стоит ли ее называть ошибкой? Так говорят только потому, что программист думает оней как об ошибке, а механизм особых ситуаций является средством обработки ошибок.

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

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

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