Главная » Просмотр файлов » С. Мейерс - Эффективный и современный C++

С. Мейерс - Эффективный и современный C++ (1114942), страница 35

Файл №1114942 С. Мейерс - Эффективный и современный C++ (С. Мейерс - Эффективный и современный C++) 35 страницаС. Мейерс - Эффективный и современный C++ (1114942) страница 352019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

. . Ts>std : : unique_ptr<T> make_unique (Ts&& . . . params )return std: : unique_pt r<T> (new T ( st d : : forward<Ts> (params ) . . . ) ) ;Как вы можете видеть, ma ke_unique просто выполняет прямую передачу своих пара­метров в конструктор создаваемого объекта, создает s t d : : unique_pt r из обычного ука­зателя, возвращаемого оператором new, и возвращает этот указатель st d : : unique_pt r.Функция в данном виде не поддерживает массивы или пользовательские удалители (см.раздел 4. 1 ), но зато демонстрирует, как с минимальными усилиями можно при необхо­димости создать make_unique'. Только не помещайте вашу версию в пространство именs t d, поскольку иначе вы можете столкнуться с коллизией имен при обновлении реализа­ции стандартной библиотеки до С++ 14.Функции s t d : : make_unique и s t d : : ma ke_shared представляют собой две из трехmа kе-функций, т.е.

функций, которые принимают произвольное количество аргумен­тов, выполняют их прямую передачу конструктору объекта, создаваемого в динамиче­ской памяти, и возвращают интеллектуальный указатель на этот объект. Третья mаkе­функция s t d : : a llocate_shared. Она работает почти так же, как и s t d : : ma ke_shared,за исключением того, что первым аргументом является объект распределителя, использу­ющийся для выделения динамической памяти.Даже самое тривиальное сравнение создания интеллектуального указателя с помо­щью mаkе-функции и без участия таковой показывает первую причину, по которой при­менение таких функций является предпочтительным. Рассмотрим следующий код.-auto upwl ( std : : make_unique<Widget> ( ) ) ;11 С mаkе - функциейstd : : unique_pt r<Widget> upw2 ( new Widget) ; / / Без mаkе - функцииauto spwl ( std : : make_shared<Widget> ( ) ) ;/! С mаkе -функциейstd : : shared_ptr<Widget> spw2 ( new Widget) ; / / Без mаkе - функцииЯ подчеркнул важное отличие: версия с применением оператора new повторяет соз­данный тип, в то время как mа kе-функции этого не делают.

Повторение типа идет враз­рез с основным принципом разработки программного обеспечения: избегать дублиро­вания кода. Дублирование в исходном тексте увеличивает время компиляции, можетвести к раздутому объектному коду и в общем случае приводит к коду, с которым слож­но работать. Зачастую это ведет к несогласованному коду, а несогласованности в кодечасто ведут к ошибкам. Кроме того, чтобы набрать на клавиатуре что-то дважды, надо3Дня создания полнофункциональной версии make unique с минимальными усилиями поищитедокумент, ставший ее источником, и скопируйте из него ее реализацию. Этот документ N3656от 18 апреля 20 1 3 года, его автор - Стивен Т.

Лававей (Stephan Т. Lavavej)._-4.4. Предпочитайте использование std::make_unique и std::make_shared ""1 47затратить в два раза больше усилий, чем для единственного набора, а кто из нас не любитсократить эту работу?Второй причиной для предпочтения mа kе-функций является безопасность исключе­ний. Предположим, что у нас есть функция для обработки Widget в соответствии с не­которым приоритетом:void processWidget ( std: : shared_ptr<Widget> spw, int priori ty ) ;Передача std : : sha red_pt r по значению может выглядеть подозрительно, но в разде­ле 8.

1 поясняется, что если processWidget всегда делает копию s t d : : shared_ptr (напри­мер, сохраняя ее в структуре данных, отслеживающей обработанные объекты Widget ) , тоэто может быть разумным выбором.Предположим теперь, что у нас есть функция для вычисления приоритетаint computePriority ( ) ;и мы используем ее в вызове proces sWidget, который использует оператор new вместоstd : : make shared:proces sWidget (std : : shared_ptr<Widget> ( new Widge t ) ,computePriorit y ( ) ) ;/ / Потенциальная/ / утечка/ / ресурсаКак указывает комментарий, этот код может приводить к утечке Widget, вызваннойприменением new.

Но почему? И вызывающий код, и вызываемая функция используютуказатели s td : : shared_pt r, а s t d : : shared_pt r спроектированы для предотвращенияутечек ресурсов. Они автоматически уничтожают то, на что указывают, когда исчезаетпоследний std : : shared_ptr.

Если все везде используют указатели std : : shared_ptr,о какой утечке может идти речь?Ответ связан с тем, как компиляторы транслируют исходный код в объектный. Вовремя выполнения аргументы функции должны быть вычислены до вызова функции,так что в вызове processWidget до того, как processWidget начнет свою работу, должнопроизойти следующее.•Выражение new W idget должно быть вычислено, т.е. в динамической памяти дол­жен быть создан объект W idget.•Должен быть вызван конструктор s t d : : shared _pt r<W i dget >, отвечающий зауправление указателем, сгенерированным оператором new.•Должна быть вызвана функция computePriority.Компиляторы не обязаны генерировать код, выполняющий перечисленные действияименно в таком порядке.

Выражение new W idget должно быть выполнено до вызоваконструктора std : : shared_pt r, поскольку результат этого оператора new используетсяв качестве аргумента конструктора, но функция computePriori ty может быть выполненадо указанных вызовов, после них или, что критично, между ними, т.е. компиляторы мо­гут генерировать код для выполнения операций в следующем порядке.1 48Глава 4 . Интеллектуальные указатели1 .

Выполнить new Widget.2. Выполнить computePriority.3. Вызвать конструктор std : : shared_pt r.Если сгенерирован такой код и во время выполнения computePriority генерирует ис­ключение, созданный на первом шаге в динамической памяти Widget будет потерян, таккак он не будет сохранен в указателе s t d : : shared_pt r, который, как предполагается,начнет управлять им на третьем шаге.Применение std : : ma ke_shared позволяет избежать таких проблем. Вызывающий кодимеет следующий вид:processWidget ( std: : make_shared<Widget> ( ) , / / Потенциальнойcompute Priority ( ) ) ;1 1 утечки ресурсов нетВо время выполнения либо s t d : : ma ke s ha red, либо compu t e P r i o r i t y будет вы­звана первой. Если это s t d : : ma ke_sha red, обычный указатель на созданный в ди­намической памяти W idget будет безопасно сохранен в возвращаемом указателеstd : : shared_pt r до того, как будет вызвана функция compute P ri o r i t y.

Если послеэтого функция computePriority сгенерирует исключение, деструктор std : : sha red_ptrуничтожит объект W idget, которым владеет. А если первой будет вызвана функцияcomputePriority и сгенерирует при этом исключение, то std: : ma ke_shared даже не бу­дет вызвана, так что не будет создан объект Widget, и беспокоиться будет не о чем.Если мы заменим std : : shared_pt r и std : : make_shared указателем std : : unique_ptrи функцией std: : make_unique, все приведенные рассуждения останутся в силе.

Исполь­зование std : : make unique вместо new так же важно для написания безопасного с точкизрения исключений кода, как и применение s t d : : ma ke_ shared.Особенностью std : : make_ shared (по сравнению с непосредственным использовани­ем new) является повышенная эффективность.

Применение std: : make_shared позволяеткомпиляторам генерировать меньший по размеру и более быстрый код, использующийболее компактные структуры данных. Рассмотрим следующее непосредственное приме­нение оператора new:std: : shared_ptr<Widget> spw ( new Widget ) ;Очевидно, что этот код предполагает выделение памяти, но фактически он выполняетдва выделения. В разделе 4.2 поясняется, что каждый указатель std : : shared_pt r ука­зывает на управляющий блок, содержащий, среди прочего, значение счетчика ссылокдля указываемого объекта. Память для этого блока управления выделяется в конструкто­ре std : : shared_pt r. Непосредственное применение оператора new, таким образом, тре­бует одного выделения памяти для Widget и второго - для управляющего блока.Если вместо этого использовать std: : ma ke shared,auto spw=std : : ma ke_shared<Widget> ( ) ;то окажется достаточно одного в ыделения памяти.

Дело в том, что функцияs t d : : ma ke _ shared выделяет один блок памяти для хранения как объекта Widget, так4.4. Предпочитайте испоnьзование std::make_unique и std::make_shared....1 49и управляющего блока. Такая оптимизация снижает статический размер программы, по­скольку код содержит только один вызов распределения памяти и повышает скоростьработы выполнимого кода, так как выполняется только одно выделение памяти. Крометого, применение std : : make_shared устраняет необходимость в некоторой учетной ин­формации в управляющем блоке, потенциально уменьшая общий объем памяти, требу­ющийся для программы.Анализ эффективности функции s t d : : ma ke_shared в равной мере применим и кstd : : а l loca t e shared, так что преимущество повышения производительности функ­ции std : : ma ke_shared распространяется и на нее.Аргументы в пользу предпочтения mаkе-функций непосредственному использованиюоператора new весьма существенны.

Тем не менее, несмотря на их проектные преиму­щества, безопасность исключений и повышенную производительность, данный разделговорит о пред почтительном применении mа kе-функций, но не об их исключительномиспользовании. Дело в том, что существуют ситуации, когда эти функции не могут илине должны использоваться.Например, ни одна из mаkе-функций не позволяет указывать пользовательскиеудалители (см. разделы 4.

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

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

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

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