Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - [51]

Шрифт
Интервал

Следует запомнить

• Специальные функции-члены — это те функции-члены, которые компиляторы могут генерировать самостоятельно: конструктор по умолчанию, деструктор, копирующие и перемещающие операции.

• Перемещающие операции генерируются только для классов, в которых нет явно объявленных перемещающих операций, копирующих операций и деструктора.

• Копирующий конструктор генерируется только для классов, в которых нет явно объявленного копирующего конструктора, и удаляется, если объявляется перемещающая операция. Копирующий оператор присваивания генерируется только для классов, в которых нет явно объявленного копирующего оператора присваивания, и удаляется, если объявляется перемещающая операция. Генерация копирующих операций в классах с явно объявленным деструктором является устаревшей и может быть отменена в будущем.

• Шаблоны функций-членов не подавляют генерацию специальных функций-членов.

Глава 4

Интеллектуальные указатели

Поэты и композиторы пишут о любви. Иногда — о подсчетах. Иногда — и о том, и о другом одновременно. Стоит только вспомнить Элизабет Баррет Браунинг (Elizabeth Barrett Browning) с ее “Как я люблю тебя? Позволь мне счесть…” (How do I love thee? Let те count the ways.) и Пола Саймона (Paul Simon) с “Наверняка есть 50 способов уйти от любимого человека” (“There must be 50 ways to leave your lover”). Давайте и мы посчитаем причины, по которым так тяжело любить обычные встроенные указатели.

1. Их объявление не дает информации о том, указывают ли они на один объект или на массив.

2. Их объявление ничего не говорит о том, должны ли вы уничтожить то, на что он указывает, когда завершите работу, т.e. владеет ли указатель тем, на что указывает.

3. Если вы определили, что должны уничтожить то, на что указывает указатель, нет никакого способа указать, как это сделать. Должны ли вы использовать >delete или имеется иной механизм деструкции (например, специальная функция уничтожения, которой следует передать этот указатель)?

4. Если вам удалось выяснить, что требуется использовать оператор >delete, то причина 1 означает, что нет никакого способа узнать, следует ли использовать оператор для удаления одного объекта (>delete) или для удаления массива (>delete[]). Если вы используете оператор неверного вида, результат будет неопределенным.

5. Если вы определили, что указатель владеет тем, на что указывает, и выяснили, каким образом уничтожить то, на что он указывает, оказывается очень трудно обеспечить уничтожение ровно один раз на каждом пути вашего кода (включая те, которые возникают благодаря исключениям). Пропущенный путь ведет к утечке ресурсов, а выполнение уничтожения более одного раза — к неопределенному поведению.

6. Обычно нет способа выяснить, не является ли указатель висячим, т.e. не указывает ли он на память, которая больше не хранит объект, на который должен указывать указатель. Висячие указатели образуются, когда объекты уничтожаются, в то время как указатели по-прежнему указывают на них.

Встроенные указатели являются острым инструментом, но десятилетия опыта показывают, что достаточно малейшей небрежности или невнимательности — и об этот инструмент можно очень сильно порезаться.

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

В С++11 имеются четыре интеллектуальных указателя: >std::auto_ptr, >std::unique_ptr, >std::shared_ptr и >std::weak_ptr. Все они разработаны для того, чтобы помочь управлять временем жизни динамически выделяемых объектов, т.e. избежать утечек ресурсов, гарантируя, что такие объекты уничтожаются соответствующим образом в нужный момент (включая генерацию исключений).

Интеллектуальный указатель >std::auto_ptr является устаревшим указателем, доставшимся в наследство от С++98. Попытка его стандартизации привела к тому, что в С++11 он превратился в >std::unique_ptr. Правильное выполнение некоторых работ требовало семантики перемещения, которой не было в С++98. В качестве обходного пути был придуман интеллектуальный указатель >std::auto_ptr, который превращал операцию копирования в перемещение. Это приводило к удивительному коду (копирование >std::auto_ptr превращало его в нулевой указатель!) и к разочаровывающим ограничениям при использовании (например, было нельзя хранить >std::auto_ptr в контейнерах).

Интеллектуальный указатель >std::unique_ptr делает все то же, что и >std::auto_ptr, плюс еще кое-что. Он делает это максимально эффективно и безо всяких искажений понятия копирования объекта. Он во всех отношениях лучше >std::auto_ptr. Единственный случай обоснованного применения >std::auto_ptr — необходимость компиляции кода компилятором С++98. Если у вас нет такого ограничения, вы должны заменять


Еще от автора Скотт Мейерс
Эффективное использование STL

В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Платформа J2Me

Эта книга научит вас, как разрабатывать программное обеспечение для платформы J2ME компании «Sun Microsystems». Эта книга придерживается стиля учебного пособия, это не справочное руководство.Цель — дать вам твердую основу в понятиях и техниках, которая даст вам возможность решиться на самостоятельную разработку качественных приложений.


Виртуальная библиотека Delphi

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


Обработка баз данных на Visual Basic.NET

Это практическое руководство разработчика программного обеспечения на 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 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.