Скотт Мейерс - Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14
- Название:Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2016
- Город:Москва
- ISBN:978-5-8459-2000-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Мейерс - Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 краткое содержание
В книге рассматриваются следующие темы. Освоение С++11 и С++14 — это больше, чем просто ознакомление с вводимыми этими стандартами возможностями (например, объявлениями типов
, семантикой перемещения, лямбда-выражениями или поддержкой многопоточности). Вопрос в том, как использовать их эффективно, чтобы создаваемые программы были корректны, эффективны и переносимы, а также чтобы их легко можно было сопровождать. Именно этим вопросам и посвящена данная книга, описывающая создание по-настоящему хорошего программного обеспечения с использованием C++11 и С++14 — т.е. с использованием современного С++.
■ Преимущества и недостатки инициализации с помощью фигурных скобок, спецификации
, прямой передачи и функций
интеллектуальных указателей
■ Связь между
,
, rvalue-ссылками и универсальными ссылками
■ Методы написания понятных, корректных,
лямбда-выражений
■ Чем
отличается от
, как они используются и как соотносятся с API параллельных вычислений С++
■ Какие из лучших методов “старого” программирования на С++ (т.е. С++98) должны быть пересмотрены при работе с современным С++
Более чем 20 лет книги
серии
являются критерием уровня книг по программированию на С++. Понятное пояснение сложного технического материала принесло ему всемирную известность. Он всегда самый желанный гость на международных конференциях, а его услуги консультанта широко востребованы во всем мире.
Скотт Мейерс Эффективный и современный С++, После изучения основ С++ я перешел к изучению того, как применять С++ в промышленном программировании, с помощью серии книг Скотта Мейерса Эффективный С++. Эффективный и современный С++ — наиболее важная из книг серии, предлагающая ключевые рекомендации, стили и идиомы, позволяющие эффективно использовать современный С++. Вы еще не купили эту книгу? Сделайте это прямо сейчас. Герб Саттер,
глава Комитета ISO по стандартизации С++, специалист в области архитектуры программного обеспечения на С++ в Microsoft
Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Интеллектуальный указатель std::unique_ptr
имеет две разновидности: одну — для индивидуальных объектов ( std::unique_ptr
), а другую — для массивов ( std::unique_ptr
). В результате никогда не возникает неясность в том, на какую сущность указывает std::unique_ptr
. API std::unique_ptr
разработан так, чтобы соответствовать используемой разновидности. Например, в случае указателя для одного объекта отсутствует оператор индексирования ( operator[]
), в то время как в случае указателя для массива отсутствуют операторы разыменования ( operator*
и operator->
).
Существование std::unique_ptr
для массивов должно представлять только интеллектуальный интерес, поскольку std::array
, std::vector
и std::string
почти всегда оказываются лучшим выбором, чем встроенные массивы. Я могу привести только одну ситуацию, когда std::unique_ptr
имеет смысл — при использовании С-образного API, который возвращает встроенный указатель на массив в динамической памяти, которым вы будете владеть.
Интеллектуальный указатель std::unique_ptr
представляет собой способ выражения исключительного владения на С++11, но одной из наиболее привлекательных возможностей является та, что его можно легко и эффективно преобразовать в std::shared_ptr
:
std::shared_ptrsp = // Конвертация std: :unique_ptr
makeInvestment( arguments ); // в std::shared_ptr
Это ключевой момент, благодаря которому std::unique_ptr
настолько хорошо подходит для возвращаемого типа фабричных функций. Фабричные функции не могут знать, будет ли вызывающая функция использовать семантику исключительного владения возвращенным объектом или он будет использоваться совместно (т.e. std::shared_ptr
). Возвращая std::unique_ptr
, фабрики предоставляют вызывающим функциям наиболее эффективный интеллектуальный указатель, но не мешают им заменить этот указатель более гибким. (Информация об интеллектуальном указателе std::shared_ptr
приведена в разделе 4.2.)
• std::unique_ptr
представляет собой маленький, быстрый, предназначенный только для перемещения интеллектуальный указатель для управления ресурсами с семантикой исключительного владения.
• По умолчанию освобождение ресурсов выполняется с помощью оператора delete
, но могут применяться и пользовательские удалители. Удалители без состояний и указатели на функции в качестве удалителей увеличивают размеры объектов std::unique_ptr
.
• Интеллектуальные указатели std::unique_ptr
легко преобразуются в интеллектуальные указатели std::shared_ptr
.
4.2. Используйте std::shared_ptr
для управления ресурсами путем совместного владения
Программисты на языках программирования со сборкой мусора показывают пальцами на программистов на С++ и смеются над ними, потому что те озабочены предотвращением утечек ресурсов. “Какой примитив! — издеваются они. — Вы что, застряли в 1960-х годах и в Lisp? Управлять временем жизни ресурсов должны машины, а не люди”. Разработчики на С++ не остаются в долгу: “Вы имеете в виду, что единственным ресурсом является память, а время освобождения ресурса должно быть принципиально неопределимо? Спасибо, мы предпочитаем обобщенность и предсказуемость деструкторов!” Впрочем, в нашей браваде есть немного бахвальства. Сборка мусора в действительности достаточно удобна, а управление временем жизни вручную действительно может показаться похожим на создание микросхем памяти из шкуры медведя с помощью каменных ножей. Почему же не получается взять лучшее из двух миров — систему, которая работает автоматически (как сборка мусора) и к тому же применима ко всем ресурсам и имеет предсказуемое время выполнения (подобно деструкторам)?
Интеллектуальный указатель std::shared_ptr
представляет собой способ, которым С++11 объединяет эти два мира. Объект, доступ к которому осуществляется через указатели std::shared_ptr
, имеет время жизни, управление которым осуществляется этими указателями посредством совместного владения . Никакой конкретный указатель std::shared_ptr
не владеет данным объектом. Вместо этого все указатели std::shared_ptr
, указывающие на него, сотрудничают для обеспечения гарантии, что его уничтожение произойдет в точке, где он станет более ненужным. Когда последний указатель std::shared_ptr
, указывающий на объект, прекратит на него указывать (например, из-за того, что этот std::shared_ptr
будет уничтожен или перенаправлен на другой объект), этот std::shared_ptr
уничтожит объект, на который он указывал. Как и в случае сборки мусора, клиентам не надо самим беспокоиться об управлении временем жизни объектов, на которые они указывают, но, как и при работе с деструкторами, время уничтожения объекта оказывается строго определенным.
Указатель std::shared_ptr
может сообщить, является ли он последним указателем, указывающим на ресурс, с помощью счетчика ссылок, значения, связанного с ресурсом и отслеживающего, какое количество указателей std::shared_ptr
указывает на него. Конструкторы std::shared_ptr
увеличивают этот счетчик (обычно увеличивают — см. ниже), деструкторы std::shared_ptr
уменьшают его, а операторы копирующего присваивания делают и то, и другое. (Если sp1
и sp2
являются указателями std::shared_ptr
, указывающими на разные объекты, присваивание “ sp1 = sp2;
” модифицирует sp1
так, что он указывает на объект, на который указывает sp2
. Конечным результатом присваивания является то, что счетчик ссылок для объекта, на который изначально указывал sp1
, уменьшается, а значение счетчика для объекта, на который указывает sp2
, увеличивается.) Если std::shared_ptr
после выполнения декремента видит нулевой счетчик ссылок, это означает, что на ресурс не указывает больше ни один std::shared_ptr
, так что наш интеллектуальный указатель освобождает этот ресурс.
Наличие счетчиков ссылок влияет на производительность.
• Размер std::shared_ptr
в два раза больше размера обычного указателя, поскольку данный интеллектуальный указатель содержит обычный указатель на ресурс и другой обычный указатель на счетчик ссылок [12] Стандарт не требует использования именно такой реализации, но все известные мне реализации стандартной библиотеки поступают именно так
.
• Память для счетчика ссылок должна выделяться динамически. Концептуально счетчик ссылок связан с объектом, на который он указывает, однако сам указываемый объект об этом счетчике ничего не знает. В нем нет места для хранения счетчика ссылок. (Приятным следствием этого является то, что интеллектуальный указатель std::shared_ptr
может работать с объектами любого типа (в том числе встроенных типов).) В разделе 4.4 поясняется, что можно избежать стоимости динамического выделения при создании указателя std::shared_ptr
с помощью вызова std::make_shared
, однако имеются ситуации, когда функция std::make_shared
неприменима. В любом случае счетчик ссылок хранится в динамически выделенной памяти.
Интервал:
Закладка: