Главная » Просмотр файлов » Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003)

Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (1160769), страница 72

Файл №1160769 Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003)) 72 страницаД. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (1160769) страница 722019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Таким образом, копирование — неподходящая операция для хранителей обьектов. Вместо этого следует говорить, скорее, о передаче объектов от' одного хранителя другому. Операция передачи легко осуществляется с помощью операции освобождения объекта, за которой следует инициализация или присвоение. НОЫЕГ<ЯОВЕт)ЗЯПд> )т1(ПЕМ ЯОтЕс)ттнд); Но1с)ег<ЯомеГМпд> )з2()з1.ге1еаве()); Заметим еше раз, что синтаксис НОЫег<Х> )т = р; неприменим, поскольку влечет за собой неявное преобразование типов, в то время как конструктор объявлен как ехр11стт: Но1с)ег<Яотет)ттпд> )г2 = )з1.ге1еаве[); // ОШИБКА 20.1. Но!бег и Тгп!е 397 20.1.7. Копирование Но16ег при вызовах функций Явная передача работает вполне корректно, однако ситуация несколько усложняется, если передача осуществляется через границы вызова функций. Для случая передачи Но1с)ег от вызывающей функции в вызываемую всегда можно воспользоваться передачей по ссылке, а не по значению.

Использование освобождения с последующей инициализацией может привести к проблемам при передаче нескольких аргументов. НуС1авв х; са11ее(Ы.ге1еаве(),х); // Передача х может // сгенерировать исключение Если компилятор сначала вычислит Ы.ге1еаве(), то последующая передача х (в предположении, что осуществляется передача по значению), которая может привести к генерации исключения, вызовет утечку памяти, поскольку у объекта, хранившегося в Ь1, больше не будет владельца. Поэтому класс Но1с)ег всегда следует передавать только по ссылке. К сожалению, возврат хранителя объекта по ссылке далеко не всегда удобен, поскольку приводит к тому, что время жизни хранителя должно превышать вызов функции, а это, в свою очередь, не способствует ясному пониманию того, когда и как должен быть освобожден хранимый обьект.

Как вариант, можно вызвать функцию ге1еаве () непосредственно перед возвратом из функции. Рассмотрим следующий код: Яоюес)зепд* сгеасог() Но1г(ег<Яотек)зхпд> Ь(пеи Яоюес)зепд); МуС1авв х; // Введен с иллюстративной целью гесигп )з.ге1еаве()г ) В этом случае необходимо отдавать себе отчет, что деструкция х может вызвать исключение, которое генерируется после освобождения своего объекта хранителем )т и до того, как этот обьект получит вызывающая функция. В результате можно получить утечку ресурсов .13го еще раз подтверждает мысль о том, что генерация исключений в деструкторе — идея весьма нездоровая, особенно в том отношении, что генерация исключения в деструкторе в процессе развертывания стека при обработке предыдущего исключения приведет к немедленному завершению программы.) 20.1.8. Тгп1е Для решения проблем такого рода введем вспомогательный шаблон класса, предназначенный лля передачи хранителей.

Назовем его тги1е (от ггапзГег сараи!е — оболочка передачи) и определим, как показано ниже. // роепсегв/сги1е.)зрр ()халдей ТВАЙТ Е НРР Глава 20. Интеллектуальные указатели 398 йс)еййпе ТЫЛ Е НРР Гещр1аее сгурепаще Т> с1авв Но16егу сещр1аге сгурепаще Т> с1авв Тги1е ( ргфчаге: Т* ргг; // Объекты, с которыми работает класс ри)з11с: // Конструктор, гарантирующий, что класс используется // только как возвращаемый тип для передачи НоМег // вызывающей функции Тги1е(Но1с)егсТ>й )з) ( ргг = )з.дег() г )т.ге1еаве(); // Конструктор копирования Тги1е(Тги1есТ> сопвгй Г) ( рсг = г.рсг; сопвг савгстги1ест>й>(с).ргг = о; // Деструктор -Тги1е() ( с1е1есе ргг; ргйчаге: // Запрещено использование в качестве 1ча1ие // и копирующее присвоение Тги1е(Тги1есТ>й); Тги1есТ>й орегасог (Тги1есТ>й)г бг1епд с1авв НоЫегсТ>у ()еп61Й // Тй(Л Е НРР Очевидно, что конструктор копирования выглядит довольно безобразно.

Поскольку шаблон Тги1е предназначен для работы в качестве возвращаемого типа функции, его объекты всегда выступают в роли временных (гча!ие); следовательно, они могут оказаться ограниченными ссылкой на константный тип. Однако передача не может быть копированием и должна забрать владение объектом у исходного Тги1е, присвоив соответствующему указателю нулевое значение. Очеввщно, что это не константная операция. То, что сделано нами в конструкторе тги1е, выглядит безобразно, но вполне корректно, 20.1. Но1дег и Тго1е 399 если передаваемый объект на самом деле константным не является. Следовательно, при использовании шаблона Тги1е вы должны быть внимательны и объявлять возвращаемый тип функции как Тги1е<Т>, но не как Тги1е<Т> сопит. Заметим, что такого рода код при преобразовании Но1йег в Тги1е не используется: Но1йег должен быть неконстантным 1ча1ие.

Вот почему был использован отдельный тип для передачи вместо объединения необходимой нам функциональности в одном шаблоне с функциональностью Но1йег. Чтобы запретить использование Тги1е где бы то ни было помимо возвращаемого типа для передачи Но1йег, конструктор копирования, получающий ссылку на неконстантный объект, и аналогичный оператор присвоения объявлены закрытыми. Это позволяет избежать использования объектов Тги1е в качестве )ча1пе, но достаточной эта мера не является. Однако назначение этого шаблона — помочь программисту, а не помешать ополоумевшему хакеру. Шаблон Тги1е не будет полон до тех пор, пока не будет распознаваться шаблоном Но1йег. // ройпсегв/)то1йег2ехсг.)трр Сешр1аее <Сурепагее Т> с1авв Но1йег ( // Ранее определенные члены //.

ри)>11с: но1йег(тги1е<т> сопвса с) ( рсг = с.рсг; сопве саве<Тги1е<Т>а>(с).рсг = ОГ Но1йег<Т>а орегасог= (Тги1е<Т> сопвса с) йе1еее рсгг ,рсг = с.рсг; сопвс савс<тги1е<т>а>(е).рсг пг гесигп *с)тйв; Для иллюстрации взаимодействия пары Но1йег/Тги1е можно переписать наш пример Хоай вовек)тйпо () и вызвать ее.

ййпс1ийе >)то1йег2.)трр> ййпс1ийе "сги1е.)трр< с1авв ЯогаесМпй ( Глава 20. Интеллектуальные указателе иойс) геас) вомесЫпд(ЯоазесМпд* х) Тгц1е<Яомес)з|пд> 1оас) вомес)з1пд() ( Но1с)ег<Яоаеп)з1пд> гевц1П(пеи Яомеп)з1пд)з геас) вовек)зйпд(гевц1с.дес()); гесцгп гевц1с; Тпс тайп() ( Но1с)ег<яовес)зйпд> рсг(1оас) вощег)зйпд() ); //. В завершение следует отмеппь, что нами создана пара шаблонов классов, которые практически так же удобны в обращении, как и обычные указатели, но при этом обладают тем преимуществом, что при необходимости самостоятельно управляют освобождением объектов, в частности при развертывании стека в результате генерации исключения.

20.2. Счетчики ссылок Шаблон Но1с)ег и вспомогательный шаблон Тгц1е хорошо подходят для временного хранения структур в выделенной памяти, с тем чтобы в случае генерации исключения и развертывания стека эта память была автоматически освобождена. Однако утечки памяти могут проявляться и в другом контексте, в частности когда несколько объектов обьединены в одну сложную структуру. Общее правило управления динамически распределяемыми объектами гласит: если в приложении ничто не указывает на динамически распределенный объект, то такой обьект должен быть уничтожен, а его память должна быть доступна для повторного использования.

Таким образом, нет ничего удивительного в том, что программисты по мере сил и возможностей стремятся автоматизировать выполнение этого правила. Проблема состоит только в том, как определить, что ничто больше не указывает на объект. Одна идея, многократно реализованная на практике, состоит в использовании так называемого счетчика ссылок (ге1егепсе соцпбпя). Для каждого объекта, на который может иметься указатель, хранится количество таких указателей, и, когда оно падает до нуля. объект уничтожается. для того чтобы данная стратегия была осуществима в С++, слелу ет придерживаться определенных соглашений. В частности, поскольку непрактично отслеживать создание, копирование и уничтожение обычных указателей на объект, достаточно распространенным является требование использования для работы с объектом со счетчиком ссылок только интеллектуальных указателей определенного типа.

В этом разделе рассматривается реализация таких интеллектуальных указателей со счетчиками 20.2. Счетчики ссылок 401 ссылок. Такой указатель представляет собой шаблон, главным параметром которого яв- ляется тип объекта, на который он указывает. Сешр1асе<сурепаше Т ...> с1азз Соппе1пдркг ( рпЬ11с: // Конструктор, создающий новый счетчик для // указываемого объекта ехр11с1с Соипк1пдРСг(Т*)з // Копирование увеличивает значение счетчика Соипс1пдРСг(Соцпк1пдркг<Т ...> сопвсй); // Леструктор уменьшает значение счетчика 1п11пе -СоипкхпдРСг(); // Присвоение уменьшает значение счетчика для // ранее указанного объекта, и увеличивает // значение счетчика для присваиваемого объекта // (будьте осторожны с присвоением самому себе!) СоипгхпдРСг<Т ...>й орегагог=(Соипк1пдРсг<Т...> сопвгй) // Операторы интеллектуального указателя 1п11пе Тй орегаког* (); 1п11пе Т* орегаког->()з Параметр Т представляет собой единственный необходимый для построения функционируюшего шаблона счетчика ссылок параметр.

Хотя так и хочется оставить его единственным параметром с тем, чтобы шаблон был как можно более простым и надежным, мы выбрали Соипсйпдрег для демонстрации использования параметров стратегий (концепция, рассматриваемая в главе 15, "Классы свойств и стратегий"). Комментарии в приведенном фрапченте кода поясняют обший подход к счетчикам ссылок: каждый'Конструктор, деструктор и оператор присвоения могут потенциально изменить значение счетчика ссылок (когда значение счетчика достигнет нуля, объект удаляется). 20.2.1.

Где находится счетчик Поскольку наша идея состоит в подсчете количества указателей на объект, было бы совершенно логично разместить счетчик в объекте. К сожалению, зто не совсем удачная идея, если тип указываемого объекта не предусматривает такой счетчик. Если в самом обьекте счетчика ссылок нет, его можно разместить в отдельно выделенной области памяти, которая имеет, как минимум, ту же продолжительность жизни, что и указываемый объект; иными словами, эта область памяти должна быть динамически выделена. Применение для этого стандартного:: орегасог пем нз используемого компилятора обычно дает не самые лучшие результаты в плане производительности.

402 Глава 20. Интеллектуальные указате и Этот оператор должен быль способен выделять память под объекты произвольного Размера без существенных накладных расходов, что требует определенных вычислительных компромиссов. Таким образом, при реализации счетчиков ссылок гораздо более распространено использование специализированных распределителей памяти. Менее распространенной альтернативой раздельному выделению памяти для объекта и счетчика является использование распределителя памяти специального назначения, который может выделять дополнительную память для счетчика ссылок.

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

Тип файла
DJVU-файл
Размер
5,6 Mb
Тип материала
Высшее учебное заведение

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

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