Скотт Мейерс - Эффективный и современный С++. 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 - читать книгу онлайн бесплатно, автор Скотт Мейерс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

class Warning { // Потенциально старый класс из С++98

public:

void override(); // Корректно как в С++98, так и в C++11

// (с тем же смыслом)

};

Это все, что следует сказать об override, но это не все, что следует сказать о ссылочных квалификаторах функций-членов. Я обещал, что поговорю о них позже, и вот сейчас как раз и настало это “позже”.

Если мы хотим написать функцию, которая принимает только аргументы, являющиеся lvalue, мы объявляем параметр, который представляет собой неконстантную lvalue-ссылку:

void doSomething(Widget& w); // Принимает только lvalue Widget

Если же мы хотим написать функцию, которая принимает только аргументы, являющиеся rvalue, мы объявляем параметр, который представляет собой rvalue-ссылку:

void doSomething(Widget&& w); // Принимает только rvalue Widget

Ссылочные квалификаторы функции-члена позволяют проводить такое же различие для объектов, функции-члены которых вызываются, т.e. *this. Это точный аналог модификатора constв конце объявления функции-члена, который указывает, что объект, для которого вызывается данная функция-член (т.e. *this), является const.

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

class Widget {

public:

using DataType = std::vector; // См. информацию о

// using в разделе 3.3

DataType& data() { return values; }

private:

DataType values;

};

Вряд ли это наиболее инкапсулированный дизайн, который видел свет, но оставим этот вопрос в стороне и рассмотрим, что происходит в следующем клиентском коде:

Widget w;

auto vals1 = w.data(); // Копирует w.values в vals1

Возвращаемый тип Widget::dataпредставляет собой lvalue-ссылку (чтобы быть точным — std::vector&), а поскольку lvalue-ссылки представляют собой lvalue, мы инициализируем vals1из lvalue. Таким образом, vals1создается копирующим конструктором из w.values, как и утверждает комментарий.

Теперь предположим, что у нас имеется фабричная функция, которая создает Widget:

Widget makeWidget();

и мы хотим инициализировать переменную с помощью std::vectorв Widget, возвращенном из makeWidget:

auto vals2 = makeWidget().data(); // Копирование значений в

// Widget в vals2

И вновь Widgets::dataвозвращает lvalue-ссылку, и вновь lvalue-ссылка представляет собой lvalue, так что наш новый объект ( vals2) опять является копией, построенной из valuesв объекте Widget. Однако в этот раз Widgetпредставляет собой временный объект, возвращенный из makeWidget(т.e. представляет собой rvalue), так что копирование в него std::vectorпредставляет собой напрасную трату времени. Предпочтительнее выполнить перемещение, но, поскольку dataвозвращается как lvalue-ссылка, правила С++ требуют, чтобы компиляторы генерировали код для копирования. (Имеется некоторый маневр для оптимизации на основе правила “как если бы” [5] “As if rule” — правило, согласно которому разрешены любые преобразования кода, не изменяющие наблюдаемое поведение программы. — Примеч. ред . , но было бы глупо полагаться та то, что ваш компилятор найдет способ им воспользоваться.)

Нам необходим способ указать, что, когда dataвызывается для Widget, являющегося rvalue, результат также будет представлять собой rvalue. Использование ссылочных квалификаторов для перегрузки dataдля Widget, являющихся lvalue и rvalue, делает это возможным:

class Widget {

public:

using DataType = std::vector;

DataType& data() & // Для lvalue Widget,

{ return values; } // возвращает lvalue

DataType&& data() && // Для rvalue Widget,

{ return std::move(values); } // возвращает rvalue

private:

DataType values;

};

Обратите внимание на разные возвращаемые типы перегрузок data. Перегрузка для lvalue-ссылки возвращает lvalue-ссылку (т.e. lvalue), а перегрузка для rvalue-ссылки возвращает rvalue-ссылку (которая, как возвращаемый тип функции, является rvalue). Это означает, что клиентский код ведет теперь себя так, как мы и хотели:

auto vals1 = w.data(); // Вызывает lvalue-перегрузку

// Widget::data, vals1

// создается копированием

auto vals2 = makeWidget().data(); // Вызывает rvalue-перегрузку

// Widget::data, vals2

// создается перемещением

Это, конечно, хорошо, но не позвольте теплому сиянию этого хэппи-энда отвлечь вас от истинной цели этого раздела. Эта цель в том, чтобы убедить вас, что всякий раз, когда вы объявляете в производном классе функцию, предназначенную для перекрытия виртуальной функции базового класса, вы не забывали делать это с использованием ключевого слова override.

Кстати, если функция-член использует ссылочный квалификатор, все перегрузки этой функции также должны использовать его. Это связано с тем, что перегрузки без этих квалификаторов могут вызываться как для объектов lvalue, так и для объектов rvalue. Такие перегрузки будут конкурировать с перегрузками, имеющими ссылочные квалификаторы, так что все вызовы функции будут неоднозначными.

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

• Объявляйте перекрывающие функции как override.

• Ссылочные квалификаторы функции-члена позволяют по-разному рассматривать lvalue- и rvalue-объекты ( *this).

3.7. Предпочитайте итераторы const_iteratorитераторам iterator

Итераторы const_iteratorпредставляют собой STL-эквивалент указателя на const. Они указывают на значения, которые не могут быть изменены. Стандартная практика применения constтам, где это только возможно, требует применения const_iteratorвезде, где нужен итератор, но не требуется изменять то, на что этот итератор указывает.

Это верно как для С++98, так и для C++11, но в С++98 поддержка const_iteratorносит половинчатый характер. Такие итераторы не так легко создавать, а если у вас уже имеется такой итератор, его использование весьма ограничено. Предположим, например, что вы хотите выполнить в std::vectorпоиск первого встречающегося значения 1983 (год, когда название языка программирования “С с классами” сменилось на С++), а затем вставить в это место значение 1998 (год принятия первого ISO-стандарта С++). Если в векторе нет значения 1983, вставка выполняется в конец вектора. При использовании итераторов iterator в С++98 сделать описанное просто:

std::vector values;

std::vector::iterator it =

std::find(values.begin(), values.end(), 1983);

values.insert(it, 1998);

Но iterator— в данном случае не совсем верный выбор, поскольку этот код не изменяет объект, на который указывает iterator. Переделка кода для использования const_iteratorдолжна быть тривиальной задачей… но не в С++98. Вот один из подходов, концептуально надежный, но все еще не совсем корректный:

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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