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

Тут можно читать онлайн Скотт Мейерс - Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Вильямс, год 2016. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14
  • Автор:
  • Жанр:
  • Издательство:
    Вильямс
  • Год:
    2016
  • Город:
    Москва
  • ISBN:
    978-5-8459-2000-3
  • Рейтинг:
    3/5. Голосов: 11
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 60
    • 1
    • 2
    • 3
    • 4
    • 5

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

Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - описание и краткое содержание, автор Скотт Мейерс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru
Эффективный и современный С++
В книге рассматриваются следующие темы. Освоение С++11 и С++14 — это больше, чем просто ознакомление с вводимыми этими стандартами возможностями (например, объявлениями типов
, семантикой перемещения, лямбда-выражениями или поддержкой многопоточности). Вопрос в том, как использовать их эффективно, чтобы создаваемые программы были корректны, эффективны и переносимы, а также чтобы их легко можно было сопровождать. Именно этим вопросам и посвящена данная книга, описывающая создание по-настоящему хорошего программного обеспечения с использованием C++11 и С++14 — т.е. с использованием современного С++.
■ Преимущества и недостатки инициализации с помощью фигурных скобок, спецификации
, прямой передачи и функций
интеллектуальных указателей
■ Связь между
,
, rvalue-ссылками и универсальными ссылками
■ Методы написания понятных, корректных,
лямбда-выражений
■ Чем
отличается от
, как они используются и как соотносятся с API параллельных вычислений С++
■ Какие из лучших методов “старого” программирования на С++ (т.е. С++98) должны быть пересмотрены при работе с современным С++
Более чем 20 лет книги
серии
являются критерием уровня книг по программированию на С++. Понятное пояснение сложного технического материала принесло ему всемирную известность. Он всегда самый желанный гость на международных конференциях, а его услуги консультанта широко востребованы во всем мире.
Скотт Мейерс Эффективный и современный С++, После изучения основ С++ я перешел к изучению того, как применять С++ в промышленном программировании, с помощью серии книг Скотта Мейерса Эффективный С++. Эффективный и современный С++ — наиболее важная из книг серии, предлагающая ключевые рекомендации, стили и идиомы, позволяющие эффективно использовать современный С++. Вы еще не купили эту книгу? Сделайте это прямо сейчас. Герб Саттер,
глава Комитета ISO по стандартизации С++, специалист в области архитектуры программного обеспечения на С++ в Microsoft

Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - читать онлайн бесплатно полную версию (весь текст целиком)

Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - читать книгу онлайн бесплатно, автор Скотт Мейерс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

4.5. При использовании идиомы указателя на реализацию определяйте специальные функции-члены в файле реализации

Если вам приходилось бороться со слишком большим временем построения приложения, вы, вероятно, знакомы с идиомой Pimpl (pointer to implementation, указатель на реализацию). Это методика, при которой вы заменяете члены-данные класса указателем на класс (или структуру) реализации, помещаете в него члены-данные, использовавшиеся в основном классе, и обращаетесь к ним опосредованно через указатель. Предположим, например, что наш Widgetимеет следующий вид:

class Widget { // В заголовочном файле "widget.h"

public:

Widget();

private:

std::string name;

std::vector data;

Gadget g1, g2, g3; // Gadget - некий пользовательский тип

};

Поскольку члены-данные Widgetимеют типы std::string, std::vectorи Gadget, для компиляции Widgetдолжны присутствовать соответствующие заголовочные файлы, а это означает, что клиенты Widgetдолжны включать с помощью директивы #includeзаголовочные файлы string, vectorи gadget.h. Эти заголовочные файлы увеличивают время компиляции клиентов Widget, а также делают этих клиентов зависящими от содержимого указанных заголовочных файлов. Если содержимое заголовочного файла изменяется, клиенты Widgetдолжны быть перекомпилированы. Стандартные заголовочные файлы stringи vectorменяются не слишком часто, но заголовочный файл gadget.hвполне может оказаться подвержен частым изменениям.

Применение идиомы Pimpl в С++98 могло выполняться с помощью замены членов- данных Widget обычным указателем на объявленную, но не определенную структуру:

class Widget { // Все еще в заголовочном файле "widget.h"

public:

Widget();

~Widget(); // Деструктор необходим (см. ниже)

private:

struct Impl; // Объявление структуры реализации

Impl *pImpl; // и указателя на нее

};

Поскольку Widgetбольше не упоминает типы std::string, std::vectorи Gadget, клиенты Widgetбольше не обязаны включать соответствующие заголовочные файлы для этих типов. Это ускоряет компиляцию, а кроме того, означает, что если что-то в заголовочных файлах будет изменено, это не затронет клиенты Widget.

Тип, который был объявлен, но не определен, называется неполным типом . Widget::Implявляется таким неполным типом. С неполным типом можно сделать очень немногое, но в это немногое входит объявление указателя на него. Идиома Pimpl использует эту возможность.

Первая часть идиомы Pimpl — объявление члена-данных, который представляет собой указатель на неполный тип. Вторая часть заключается в динамическом создании и уничтожении объекта, хранящего члены-данные, использующиеся в исходном классе. Соответствующий код находится в файле реализации, например для Widget— в файле widget.cpp:

#include "widget.h" // Файл реализации "widget.cpp"

#include "gadget.h"

#include

#include

struct Widget::Impl { // Определение Widget::Impl

std::string name; // с членами-данными, ранее

std::vector data; // находившимися в Widget

Gadget g1, g2, g3;

};

Widget::Widget() // Создание членов-данных

: pimpl( new Impl) // для данного объекта Widget

{}

Widget::~Widget() // Уничтожение членов-данных

{ delete pImpl;} // для данного объекта

Здесь я привожу директивы #include, чтобы было ясно, что общие зависимости от заголовочных файлов для std::string, std::vectorи Gadgetникуда не исчезли и продолжают существовать. Однако эти зависимости перемещены из файла widget.h(видимого и используемого всеми клиентами класса Widget) в файл widget.cpp(видимый и используемый только реализацией Widget). Я также подчеркнул код динамического выделения и освобождения объекта Impl. Необходимость освобождения этого объекта при уничтожении Widgetприводит к необходимости деструктора Widget.

Но я показал код С++98, от которого пахнет пылью вековой… Нет, пылью прошлого тысячелетия. Он использует обычные указатели, обычные операторы newи delete, и вообще весь он слишком сырой [15] Непереводимая игра слов, основанная на использовании для обычного указателя названия “raw pointer” (дословно — “сырой указатель”). — Примеч. пер . . Вся текущая глава построена на идее о том, что интеллектуальные указатели куда предпочтительнее обычных указателей, и если мы хотим динамически создавать объект Widget::Implв конструкторе Widgetи должны уничтожать его вместе с Widget, то для нас отлично подойдет интеллектуальный указатель std::unique_ptr (см. раздел 4.1). Заменяя обычный указатель pImplуказателем std::unique_ptr, мы получим следующий код для заголовочного файла

class Widget { // В файле "widget.h"

public:

Widget();

private:

struct Impl;

std:unique_ptr<Impl >pImpl; // Интеллектуальный указатель

}; // вместо обычного

и для файла реализации:

#include "widget.h" // В файле "widget.cpp"

#include "gadget.h"

#include

#include

struct Widget::Impl { // Как и ранее

std::string name;

std::vector data;

Gadget g1, g2, g3;

};

Widget::Widget() // Согласно разделу 4.4

: pImpl( std::make_unique<Impl >()) // создаем std: :unique_ptr

{} // с помощью std::make_unique

Вы заметили, что деструктора Widgetбольше нет? Дело в том, что нет никакого кода, который требуется в нем разместить. std::unique_ptrавтоматически удаляет то, на что указывает, когда он сам (указатель std::unique_ptr) уничтожается, так что нам не требуется ничего удалять вручную. Это одна из привлекательных сторон интеллектуальных указателей: они устраняют необходимость утруждать свои руки вводом кода для освобождения ресурсов вручную.

Этот код компилируется, но, увы, это не самый тривиальный клиент!

#include "widget.h"

Widget w; // Ошибка!

Получаемое вами сообщение об ошибке зависит от используемого компилятора, но в общем случае текст упоминает что-то о применении sizeofили deleteк неполному типу. Эти операции не входят в число тех, которые можно делать с такими типами.

Эта явная неспособность идиомы Pimplиспользовать std::unique_ptrвызывает тревогу, поскольку (1) указатели std::unique_ptrразрекламированы как поддерживающие неполные типы, и (2) идиома Pimpl — один из наиболее распространенных случаев применения std::unique_ptr. К счастью, этот код легко сделать работающим. Все, что для этого требуется, — понимание причины проблемы.

Проблема возникает из-за кода, который генерируется при уничтожении w(например, при выходе переменной за пределы области видимости). В этой точке вызывается ее деструктор. Если определение класса использует std::unique_ptr, мы не объявляем деструктор, так как нам нечего в него поместить. В соответствии с обычными правилами генерации специальных функций-членов компиляторами (см. раздел 3.11) этот деструктор создается вместо нас компилятором. В этот деструктор компилятор вносит код вызова деструктора члена-данных pImplкласса Widget.pImplпредставляет собой указатель std::unique_ptr, т.e. указатель std::unique_ptr, использующий удалитель по умолчанию. Удалитель по умолчанию является функцией, которая применяет оператор deleteк обычному указателю внутри std::unique_ptr. Однако перед тем как использовать delete, реализации удалителя по умолчанию в C++11 обычно применяют static_assert, чтобы убедиться, что обычный указатель не указывает на неполный тип. Когда компилятор генерирует код для деструкции Widget w, он в общем случае сталкивается с неудачным static_assert, что и приводит к выводу сообщения об ошибке. Это сообщение обычно связано с точкой, в которой происходит уничтожение w, поскольку деструктор Widget, подобно всем генерируемым компиляторами специальным функциям-членам, неявно является inline. Сообщение часто указывает на строку, в которой создается w, поскольку она представляет собой исходный текст, явно создающий объект, приводящий впоследствии к неявной деструкции.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Скотт Мейерс читать все книги автора по порядку

Скотт Мейерс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14, автор: Скотт Мейерс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x