Скотт Мейерс - Эффективный и современный С++. 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 Person {

public:

template // Конструктор с прямой передачей

explicit Person(T&& n)

: name(std::forward(n)) {}

explicit Person(int idx); // Конструктор от int

Person(const Person& rhs);// Копирующий конструктор

// (сгенерирован компилятором)

Person(Person&& rhs); // Перемещающий конструктор

// (сгенерирован компилятором)

};

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

Person p("Nancy");

auto cloneOfP(p); // Создание нового объекта Person из p;

// этот код не компилируется!

Здесь мы пытаемся создать объект Personиз другого объекта Person, что представляется очевидным случаем копирующего конструирования ( pявляется lvalue, так что можно выбросить из головы все фантазии на тему “копирования” с помощью операции перемещения). Но этот код не вызывает копирующий конструктор — он вызывает конструктор с прямой передачей. Затем эта функция будет пытаться инициализировать член-данные std::stringобъекта Personзначением из объекта Person( p). Класс std::string не имеет конструктора, получающего параметр типа Person, так что ваш компилятор будет вынужден просто развести руками и наказать вас длинными и непонятными сообщениями об ошибках.

“Но почему, — можете удивиться вы, — вызывается конструктор с прямой передачей, а не копирующий конструктор? Мы же инициализируем Personдругим объектом Person!” Да, это так, но компиляторы приносят присягу свято соблюдать правила С++, а правила, имеющие отношение к данной ситуации, — это правила разрешения вызовов перегруженных функций.

Компиляторы рассуждают следующим образом. cloneOfPинициализируется неконстантным lvalue ( p), а это означает, что шаблонный конструктор может быть инстанцирован для получения неконстантного lvalue типа Person. После такого инстанцирования класс Personвыглядит следующим образом:

class Person {

public:

explicit Person(Person& n) // Инстанцирован из

: name(std::forward(n)) {} // шаблона с прямой

// передачей

explicit Person(int idx); // Как и ранее

Person(const Person& rhs); // Копирующий конструктор

// (сгенерирован компилятором)

};

В инструкции

auto cloneOfP(p);

pможет быть передан либо копирующему конструктору, либо инстанцированному шаблону. Вызов копирующего конструктора для точного соответствия типа параметра требует добавления к pмодификатора const; вызов инстанцированного шаблона никаких добавлений не требует. Таким образом, перегрузка, сгенерированная из шаблона, представляет собой лучшее соответствие, так что компиляторы делают то, для чего предназначены: генерируют вызов той функции, которая соответствует наилучшим образом. “Копирование” неконстантных lvalue типа Person, таким образом, осуществляется конструктором с прямой передачей, а не копирующим конструктором.

Если мы немного изменим пример, так, чтобы копируемый объект был константным, то увидим совершенно иную картину:

constPerson cp("Nancy"); // Теперь объект константный

auto cloneOfP(cp); // Вызов копирующего конструктора!

Поскольку копируемый объект теперь объявлен как const, он в точности соответствует типу параметра, получаемого копирующим конструктором. Шаблонизированный конструктор также может быть инстанцирован таким образом, чтобы иметь ту же сигнатуру:

class Person public:

explicit Person(const Person& n);// Инстанцирован из шаблона

Person (const Person& rhs); // Копирующий конструктор

// (сгенерирован компилятором)

};

Но это не имеет значения, поскольку одно из правил разрешения перегрузок в С++ гласит, что в ситуации, когда инстанцирование шаблона и нешаблонная функция (т.e. "нормальная" функция) имеют одинаково хорошее соответствие, предпочтение отдается нормальной функции. Поэтому все козыри оказываются на руках копирующего конструктора (нормальной функции) с той же самой сигнатурой.

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

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

class SpecialPerson: public Person {

public:

SpecialPerson(const SpecialPerson& rhs) // Копирующий

: Person(rhs) // конструктор; вызывает конструктор

{ … } // базового класса с прямой передачей!

SpecialPerson(SpecialPerson&& rhs) // Перемещающий

: Person(std::move(rhs))// конструктор; вызывает конструктор

{ … } // базового класса с прямой передачей!

};

Как указывают комментарии, копирующий и перемещающий конструкторы производного класса не вызывают копирующий и перемещающий конструкторы базового класса; они вызывают конструктор базового класса с прямой передачей! Чтобы понять, почему, обратите внимание, что функции производного класса используют аргументы типа SpecialPersonдля передачи в базовый класс, после чего в игру вступает разрешение перегрузок для конструкторов в классе Person. В конечном итоге код не будет компилироваться, потому что у std::stringнет никакого конструктора, принимающего SpecialPerson.

Я надеюсь, что теперь я убедил вас, что перегрузка для параметров, являющихся универсальными ссылками, — это то, чего лучше избегать, насколько это возможно. Но если перегрузка для универсальной ссылки — плохая идея, то что же делать, если вам нужна функция, которая выполняет передачу большинства типов аргументов, но при этом должна обрабатывать некоторые из них особым образом? Это яйцо может быть разбито массой способов. Этих способов так много, что я посвятил им целый раздел — раздел 5.5, который идет сразу после того, который вы сейчас читаете. Не останавливайтесь, и вы попадете прямо в него.

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

• Перегрузка для универсальных ссылок почти всегда приводит к тому, что данная перегрузка вызывается чаще, чем вы ожидаете.

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

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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