Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - [58]
>std::enable_shared_from_this
.Шаблон >std::enable_shared_from_this
определяет функцию-член, которая создает >std::shared_ptr
для текущего объекта, но делает это, не дублируя управляющие блоки. Это функция-член >shared_from_this
, и вы должны использовать ее в функциях-членах тогда, когда вам нужен >std::shared_ptr
, который указывает на тот же объект, что и указатель >this
. Вот как выглядит безопасная реализация >Widget::process
:
>void Widget::process() {
> // Как и ранее, обработка Widget
> …
> // Добавляем std::shared_ptr, указывающий на
> // текущий объект, в processedWidgets
> processedWidgets.emplace_back(shared_from_this());
>}
Внутри себя >shared_from_this
ищет управляющий блок текущего объекта и создает новый >std::shared_ptr
, который использует этот управляющий блок. Дизайн функции полагается на тот факт, что текущий объект имеет связанный с ним управляющий блок. Чтобы это было так, должен иметься уже существующий указатель >std::shared_ptr
(например, за пределами функции-члена, вызывающей >shared_from_this
), который указывает на текущий объект. Если такого >std::shared_ptr
нет (т.e. если текущий объект не имеет связанного с ним управляющего блока), результатом будет неопределенное поведение, хотя обычно >shared_from_this
генерирует исключение.
Чтобы препятствовать клиентам вызывать функции-члены, в которых используется >shared_from_this
, до того как на объект будет указывать указатель >std::shared_ptr
, классы, наследуемые от >std::enable_shared_from_this
, часто объявляют свои конструкторы как private и заставляют клиентов создавать объекты путем вызова фабричных функций, которые возвращают указатели >std::shared_ptr
. Например, класс >Widget
может выглядеть следующим образом:
>class Widget: public std::enable_shared_from_this
>public:
> // Фабричная функция, пересылающая
> // аргументы закрытому конструктору:
> template
> static std::shared_ptr
> …
> void process(); // Как и ранее
> …
>private:
> … // Конструкторы
>};
В настоящее время вы можете только смутно припоминать, что наше обсуждение управляющих блоков было мотивировано желанием понять, с какими затратами связано применение >std::shared_ptr
. Теперь, когда мы понимаем, как избегать создания слишком большого количества управляющих блоков, вернемся к нашей первоначальной теме.
Управляющий блок обычно имеет размер в несколько слов, хотя пользовательские удалители и распределители памяти могут его увеличить. Обычная реализация управляющего блока оказывается более интеллектуальной, чем можно было бы ожидать. Она применяет наследование, и при этом даже имеются виртуальные функции. (Все это требуется для того, чтобы обеспечить корректное уничтожение указываемого объекта.) Это означает, что применение указателей >std::shared_ptr
берет на себя также стоимость механизма виртуальной функции, используемой управляющим блоком.
Возможно, после того как вы прочли о динамически выделяемых управляющих блоках, удалителях и распределителях неограниченного размера, механизме виртуальных функций и атомарности работы со счетчиками ссылок, ваш энтузиазм относительно >std::shared_ptr
несколько угас. Это нормально.
Они не являются наилучшим решением для любой задачи управления ресурсами. Но для предоставляемой ими функциональности цена >std::shared_ptr
весьма разумна. В типичных условиях, когда использованы удалитель и распределитель памяти по умолчанию, а >std::shared_ptr
создается с помощью >std::make_shared
, размер управляющего блока составляет около трех слов, и его выделение, по сути, ничего не стоит. (Оно встроено в выделение памяти для указываемого им объекта. Дополнительная информация об этом приведена в разделе 4.4.) Разыменование >std::shared_ptr
не более дорогостояще, чем разыменование обычного указателя. Выполнение операций, требующих работы со счетчиком ссылок (например, копирующий конструктор или копирующее присваивание, удаление) влечет за собой одну или две атомарные операции, но эти операции обычно отображаются на отдельные машинные команды, так что, хотя они могут быть дороже неатомарных команд, они все равно остаются отдельными машинными командами. Механизм виртуальных функций в управляющем блоке обычно используется только однажды для каждого объекта, управляемого указателями >std::shared_ptr
: когда происходит уничтожение объекта.
В обмен на эти весьма скромные расходы вы получаете автоматическое управление временем жизни динамически выделяемых ресурсов. В большинстве случаев применение >std::shared_ptr
значительно предпочтительнее, чем ручное управление временем жизни объекта с совместным владением. Если вы сомневаетесь, можете ли вы позволить себе использовать >std::shared_ptr
, подумайте, точно ли вам нужно обеспечить совместное владение. Если вам достаточно или даже может быть достаточно исключительного владения, лучшим выбором является
В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.
Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.
Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Эта книга научит вас, как разрабатывать программное обеспечение для платформы J2ME компании «Sun Microsystems». Эта книга придерживается стиля учебного пособия, это не справочное руководство.Цель — дать вам твердую основу в понятиях и техниках, которая даст вам возможность решиться на самостоятельную разработку качественных приложений.
Это практическое руководство разработчика программного обеспечения на Visual Basic .NET и ADO.NET, предназначенное для создания приложений баз данных на основе WinForms, Web-форм и Web-служб. В книге описываются практические способы решения задач доступа к данным, с которыми сталкиваются разработчики на Visual Basic .NET в своей повседневной деятельности. Книга начинается с основных сведений о создании баз данных, использовании языка структурированных запросов SQL и системы управления базами данных Microsoft SQL Server 2000.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.