C++20 для программистов
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  C++20 для программистов

 

Пол Дейтел, Харви Дейтел
C++20 для программистов
2024

Переводчики В. Здобнов, М. Фатеев


 

Пол Дейтел, Харви Дейтел

C++20 для программистов. — СПб.: Питер, 2024.

 

ISBN 978-5-4461-2359-9

© ООО Издательство "Питер", 2024

 

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

 

Предисловие

Добро пожаловать в «C++20 для программистов. Метод готовых объектов». В этой книге представлены передовые информационные технологии для разработчиков программного обеспечения. Она соответствует стандарту C++20 (1834 страницы), который был утвержден Комитетом ISO по стандартам C++ в сентябре 2020 года1, 2.

Язык программирования C++ используется для создания высокопроизводительного, критически важного и надежного программного обеспечения. На нем пишут операционные системы, системы реального времени, встраиваемое ПО, видеоигры, банковское ПО, системы управления авиатранспортом, системы связи и многие другие программы. Эта книга представляет собой учебное пособие вводного и среднего уровня, предназначенное для освоения языка C++ (в том числе его стандартной библиотеки) в версии C++20, которая относится к самым популярным в мире языкам программирования. Мы представляем наглядный, современный, насыщенный примерами кода, ориентированный на практические задачи вводный курс C++20. Из этого предисловия вы узнаете о сути нашей книги.


1 Финальный проект стандарта C++ опубликован по адресу https://timsong-cpp.github.io/cppwp/n4861. Эта версия бесплатна. Официальную версию в печатном виде (ISO/IEC 14882:2020) можно приобрести по адресу https://www.iso.org/standard/79358.html.

2 Херб Саттер (Herb Sutter), «C++20 Approved, C++23 Meetings and Schedule Update», 6 сен­тября 2020 г. Был доступен: 15 сентября 2023 г. https://herbsutter.com/2020/09/06/c20-approved-c23-meetings-and-schedule-update.

Финальный проект стандарта C++ опубликован по адресу https://timsong-cpp.github.io/cppwp/n4861. Эта версия бесплатна. Официальную версию в печатном виде (ISO/IEC 14882:2020) можно приобрести по адресу https://www.iso.org/standard/79358.html.

Херб Саттер (Herb Sutter), «C++20 Approved, C++23 Meetings and Schedule Update», 6 сен­тября 2020 г. Был доступен: 15 сентября 2023 г. https://herbsutter.com/2020/09/06/c20-approved-c23-meetings-and-schedule-update.

1, 2
1, 2

Современный C++

В центре внимания — современный C++, включающий четыре последних стандарта: C++20, C++17, C++14 и C++11. Мы также упоминаем основные дополнения, которые могут появиться в C++23 или в более поздних версиях. Общей темой этой книги является акцент на новых, усовершенствованных способах написания кода на C++. Мы используем лучшие практики, делая акцент на современных идиомах современного профессионального программирования на C++, а также уделяем большое внимание вопросам производительности, безопасности и проектирования программного обеспечения.

В курсе событий

«Кто дерзает учить, должен никогда не переставать учиться»3. (Дж. К. Дана)

Чтобы «почувствовать пульс» современного языка C++, меняющего многие методы работы программистов, мы изучили около 6000 актуальных статей, исследовательских работ, технических описаний, документов, постов в блогах и форумах, а также видеопубликаций.


3 Джон Коттон Дана (John Cotton Dana). «В 1912 г. Дана, библиотекарь из Ньюарка, получил просьбу подобрать латинскую цитату для надписи на новом здании Государственного колледжа Ньюарка (ныне Университет Кин) в Юнионе (штат Нью-Джерси). Не найдя подходящей цитаты, Дана сочинил фразу, ставшую девизом колледжа. The New York Times Book Review, 5 марта 1967 г., с. 55. https://www.bartleby.com/73/1799.html.

Джон Коттон Дана (John Cotton Dana). «В 1912 г. Дана, библиотекарь из Ньюарка, получил просьбу подобрать латинскую цитату для надписи на новом здании Государственного колледжа Ньюарка (ныне Университет Кин) в Юнионе (штат Нью-Джерси). Не найдя подходящей цитаты, Дана сочинил фразу, ставшую девизом колледжа. The New York Times Book Review, 5 марта 1967 г., с. 55. https://www.bartleby.com/73/1799.html.

«Кто дерзает учить, должен никогда не переставать учиться»3. (Дж. К. Дана)

Кому пригодится эта книга

Книга «C++20 для программистов. Метод готовых объектов» рассчитана на следующие целевые аудитории:

• разработчики программ на C++, которые хотят изучить новейшие возможности C++20 по подробному учебнику, написанному в профессиональном стиле;

• разработчики программ на других языках, которые готовятся к выполнению проекта на языке C++ и хотят изучить его актуальную версию;

• разработчики, которые изучали C++ в вузе или работали с ним много лет назад, а теперь хотят освежить свои знания в контексте C++20;

• профессиональные преподаватели C++, составляющие курсы по C++20.

Готовые файлы с исходным кодом программ

В основе книги лежит фирменный подход Deitel — реальный код. Вместо отдельных фрагментов кода мы показываем язык C++ таким, каким он должен быть, на сотнях практических примеров готового кода, то есть работающих программ и выводимых ими данных.

Прочитайте раздел «Перед началом работы», который следует за этим предисловием, чтобы узнать, как подготовить свой компьютер с операционной системой Windows, macOS или Linux к выполнению более 200 приведенных в книге примеров кода, в которых около 15 тысяч строк. Для вашего удобства все эти примеры опубликованы на нашем веб-сайте и на портале GitHub в виде стандартных файлов C++ с расширениями .cpp и .h. Вы можете бесплатно загрузить их по любому из адресов4:

https://github.com/pdeitel/cplusplus20forprogrammers

• https://www.deitel.com/books/c-plus-plus-20-for-programmers

• https://deitel.com/c-plus-plus-20-for-programmers

https://deitel.com/cpp20fp

Все эти файлы готовы для компиляции как в интегрированных средах разработки, так и в компиляторах командной строки. Подробные инструкции о том, как компилировать и выполнять примеры кода с помощью трех рекомендуемых нами компиляторов, вы найдете в главе 1, в разделе 1.2. Компилируйте и запускайте соответствующие программы во время чтения книги, чтобы сделать учебный процесс более наглядным. Если у вас возникнут проблемы, вы можете связаться с нами по адресу:

deitel@deitel.com


4 А также с сайта издательства «Питер», см. раздел «От издательства». — Примеч. ред.

Прочитайте раздел «Перед началом работы», который следует за этим предисловием, чтобы узнать, как подготовить свой компьютер с операционной системой Windows, macOS или Linux к выполнению более 200 приведенных в книге примеров кода, в которых около 15 тысяч строк. Для вашего удобства все эти примеры опубликованы на нашем веб-сайте и на портале GitHub в виде стандартных файлов C++ с расширениями .cpp и .h. Вы можете бесплатно загрузить их по любому из адресов4:

А также с сайта издательства «Питер», см. раздел «От издательства». — Примеч. ред.

Три профессиональных компилятора на выбор

Мы протестировали все приведенные в книге примеры кода в последних версиях трех компиляторов:

• Visual C++® в составе интегрированной среды разработки Microsoft® Visual Studio® Community Edition — в операционной системе Windows®;

• Clang C++ (clang++) в составе интегрированной среды разработки Apple® Xcode® — в операционной системе macOS®, а также в контейнере Docker®;

• GNU® C++ (g++) — в операционной системе Linux®, а также в контейнере Docker® с установленным пакетом GNU Compiler Collection (GCC).

Когда мы писали эту книгу, почти все языковые новшества, введенные в стандарт C++20, уже были полностью реализованы во всех трех компиляторах, некоторые — только в одном или двух и лишь немногие — ни в одном из трех. Мы указываем на эти различия при необходимости и будем обновлять наш цифровой контент по мере того, как эти новшества будут внедряться производителями компиляторов. Мы также будем публиковать обновления кода в репозитории этой книги на портале GitHub:

https://github.com/pdeitel/CPlusPlus20ForProgrammers

Кроме того, мы будем публиковать обновления кода и текста на веб-странице этой книги:

https://www.deitel.com/books/c-plus-plus-20-for-programmers

Учебный метод готовых объектов

В главе 9 мы расскажем о том, как разрабатывать на языке C++20 пользовательские (то есть ваши собственные) классы, а в последующих главах продолжим рассмотрение объектно-ориентированного программирования.

Что такое готовые объекты?

В первых главах вы будете работать с уже существующими классами, выполняющими достаточно сложные задачи. Используя всего несколько простых инструкций на языке C++, вы быстро создадите объекты этих классов и заставите их «показать свою силу». Мы называем это методом готовых объектов.

Учитывая огромное количество бесплатных библиотек классов с открытым исходным кодом (open-source), созданных сообществом разработчиков C++, вы сможете выполнять сложные задачи задолго до того, как научитесь создавать свои собственные классы в главе 9. Это один из наиболее привлекательных аспектов работы с объектно-ориентированными языками, особенно с таким совершенным объектно-ориентированным языком, как C++.

Бесплатные классы

Мы обращаем ваше внимание, что в «экосистеме» C++ есть огромное количество очень полезных и совершенно бесплатных классов, доступных программистам. Основными источниками этих классов являются:

• стандартная библиотека C++;

• библиотеки, специфичные для конкретной платформы, например поставляемые с Microsoft Windows, Apple macOS или различными версиями Linux;

• бесплатные сторонние библиотеки C++, создаваемые сообществом разработчиков открытого программного обеспечения;

• коллеги-программисты, например сотрудники вашей организации.

Мы рекомендуем вам черпать вдохновение для ваших собственных программ, изучая многочисленные общедоступные программы на языке C++, публикуемые в виде открытого исходного кода на таких сайтах, как GitHub.

Проект Boost

Проект Boost предоставляет программистам 168 библиотек C++ с открытым исходным кодом5. Кроме того, в нем «выращиваются» многие языковые новшества, которые впоследствии включаются в стандартную библиотеку C++. Например, именно из проекта Boost берут начало уже вошедшие в современный C++ средства многопоточности и генерации случайных чисел, интеллектуальные указатели, кортежи, регулярные выражения, файловые системы и класс string_view6. На этой странице сайта Stack Overflow приведен список биб­лиотек и языковых средств современного C++, которые эволюционировали из библиотек Boost7:

https://stackoverflow.com/a/8852421

Примеры кода с готовыми объектами

В главе 1 кратко рассматриваются основные понятия и термины объектной технологии. В главах 2–8 вы будете создавать и использовать объекты уже существующих классов (задолго до создания своих собственных классов в главе 9 и далее). Наши примеры кода с готовыми объектами посвящены следующим учебным темам:

• Раздел 2.7 — создание и использование объектов класса string стандартной библиотеки.

• Раздел 3.12 — работа с очень большими целыми числами.

• Раздел 4.13 — создание и чтение ZIP-файлов.

• Раздел 5.20 — Lnfylun Lhqtomh Wjtz Qarcv: Qjwazkrplm xzz Xndmwwqhlz (это зашифрованная фраза, речь идет о шифровании с закрытым ключом).

• Раздел 6.15 — шаблон класса vector стандартной библиотеки C++.

• Раздел 7.10 — доступ к контейнерам с данными с помощью класса span (C++20).

• Раздел 8.19 — чтение и анализ CSV-файла со статистическими данными о катастрофе «Титаника».

• Раздел 8.20 — основы регулярных выражений.

• Раздел 9.22 — сериализация данных в формате JSON (JavaScript Object Nota­tion).

Прекрасный пример метода готовых объектов — использование объектов таких стандартных классов C++, как array и vector (глава 6). Вы можете работать с ними, даже не зная, как они устроены, и вообще не умея писать пользовательские классы. На протяжении всей книги мы используем обширные возможности стандартной библиотеки C++.


5 «Boost 1.78.0 Library Documentation». Был доступен: 15 сентября 2023 г. https://www.boost.org/doc/libs/1_78_0.

6 «Boost (C++ libraries)». Был доступен: 15 сентября 2023 г. https://en.wikipedia.org/wiki/Boost_(C++_libraries).

7 Kennytm, ответ на вопрос «Which Boost Features Overlap with C++11?». Был доступен: 15 сентября 2023 г. https://stackoverflow.com/a/8852421.

Проект Boost предоставляет программистам 168 библиотек C++ с открытым исходным кодом5. Кроме того, в нем «выращиваются» многие языковые новшества, которые впоследствии включаются в стандартную библиотеку C++. Например, именно из проекта Boost берут начало уже вошедшие в современный C++ средства многопоточности и генерации случайных чисел, интеллектуальные указатели, кортежи, регулярные выражения, файловые системы и класс string_view6. На этой странице сайта Stack Overflow приведен список биб­лиотек и языковых средств современного C++, которые эволюционировали из библиотек Boost7:

Проект Boost предоставляет программистам 168 библиотек C++ с открытым исходным кодом5. Кроме того, в нем «выращиваются» многие языковые новшества, которые впоследствии включаются в стандартную библиотеку C++. Например, именно из проекта Boost берут начало уже вошедшие в современный C++ средства многопоточности и генерации случайных чисел, интеллектуальные указатели, кортежи, регулярные выражения, файловые системы и класс string_view6. На этой странице сайта Stack Overflow приведен список биб­лиотек и языковых средств современного C++, которые эволюционировали из библиотек Boost7:

Проект Boost предоставляет программистам 168 библиотек C++ с открытым исходным кодом5. Кроме того, в нем «выращиваются» многие языковые новшества, которые впоследствии включаются в стандартную библиотеку C++. Например, именно из проекта Boost берут начало уже вошедшие в современный C++ средства многопоточности и генерации случайных чисел, интеллектуальные указатели, кортежи, регулярные выражения, файловые системы и класс string_view6. На этой странице сайта Stack Overflow приведен список биб­лиотек и языковых средств современного C++, которые эволюционировали из библиотек Boost7:

«Boost 1.78.0 Library Documentation». Был доступен: 15 сентября 2023 г. https://www.boost.org/doc/libs/1_78_0.

Kennytm, ответ на вопрос «Which Boost Features Overlap with C++11?». Был доступен: 15 сентября 2023 г. https://stackoverflow.com/a/8852421.

«Boost (C++ libraries)». Был доступен: 15 сентября 2023 г. https://en.wikipedia.org/wiki/Boost_(C++_libraries).

Краткое содержание книги

На внутренней стороне обложки книги показана в виде наглядной схемы ее модульная структура. Читая раздел «Краткое содержание книги», сверяйтесь с этой схемой, которая поможет быстрее ознакомиться с темами глав и разделов.

В первых главах книги закладывается прочный фундамент основ языка C++20. Последующие главы с более сложными практическими примерами кода помогут вам перейти к разработке ваших собственных программ на C++20. На протяжении всей книги рассматриваются пять моделей программирования на C++20:

• процедурное программирование;

• функциональное программирование;

• объектно-ориентированное программирование;

• обобщенное программирование;

• метапрограммирование на основе шаблонов.

Часть 1. Быстрый старт и базовые возможности C++

Глава 1 «Введение и тест-драйв популярных бесплатных компиляторов C++» рассказывает о том, что должен знать каждый профессиональный программист. В этой главе вы найдете:

• краткое введение;

• обсуждение закона Мура, многоядерных процессоров и необходимости стандартизированного конкурентного программирования в современном C++;

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

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

• Visual C++ из Microsoft Visual Studio (в Windows);

• Apple Xcode (в macOS);

• GNU g++ (в Linux).

Мы проверили на каждом из них все приведенные в книге примеры кода, прокомментировав те немногие случаи, когда наши версии компиляторов (существующие на момент выхода книги в 2022 году) еще не поддерживают какие-либо из новшеств стандарта C++20. Выберите ту среду разработки программ, которая вам больше нравится. Наши примеры кода будут хорошо работать и с другими компиляторами C++20.

Мы расскажем, как запускать компиляторы командной строки GNU g++ и clang++ в контейнерах Docker, чтобы вы могли работать с самыми современными версиями этих компиляторов в любой из трех операционных систем: Windows, macOS или Linux. Docker — это ценный инструмент разработчика, дополнительные сведения о нем приведены в разделе «Перед началом работы». Кроме того, мы расскажем, как установить Linux на компьютер с Windows, используя подсистему Windows для Linux (WSL). Это еще один способ работы в Windows с компиляторами g++ и clang++.

В главе 2 «Азы программирования на C++» представлены базовые понятия языка C++, такие как ввод и вывод данных, основные типы данных, арифметические операторы и их приоритеты, инструкции принятия решений. В разделе 2.7 вы познакомитесь с методом готовых объектов, легко создавая и используя объекты класса string стандартной библиотеки (для этого вам не надо знать, как устроен этот большой и сложный класс и как вообще устроены классы).

Глава 3 «Управляющие инструкции (часть 1)» посвящена некоторым управляющим инструкциям. В ней вы изучите инструкции выбора if и if...else, инструкции цикла while со счетчиком и контрольным значением, а также операторы инкремента, декремента и присваивания. В разделе 3.12 мы покажем очередной пример использования готовых объектов: с помощью общедоступного класса вы будете выполнять вычисления с чрезвычайно большими целыми числами.

Глава 4 «Управляющие инструкции (часть 2)» рассказывает об управляющих инструкциях for, do...while, switch, break и continue, а также о логических операторах. В разделе 4.13 вы продолжите работать с готовыми объектами, включив библиотеку miniz-cpp для записи и чтения ZIP-файлов.

В главе 5 «Функции и шаблоны функций» представлены пользовательские функции. Мы расскажем о методах моделирования на примере генерации случайных чисел. Устаревшая функция генерации случайных чисел rand, которую C++ унаследовал от языка C, может быть предсказуемой, поэтому программы с ней ненадежны. Мы рассмотрим более безопасную библиотеку, введенную в C++11, которая генерирует недетерминированные (непредсказуемые) последовательности случайных чисел. Такие генераторы случайных чисел используются для моделирования событий и в сценариях безопасности, где предсказуемость недопустима. Также мы обсудим передачу информации между функциями и рекурсию. Пример с готовыми объектами в разделе 5.20 продемонстрирует шифрование с закрытым ключом.

Часть 2. Массивы, указатели и строки

В главе 6 «Массивы, векторы, библиотека ranges и функциональное программирование» мы приступим к рассмотрению контейнеров, итераторов и алгоритмов стандартной библиотеки C++. Мы представим вам контейнер array, предназначенный для хранения и обработки списков и таблиц значений. Вы определите массивы класса array, инициализируете их и получите доступ к их элементам. Вы узнаете, как передавать эти массивы функциям, выполнять сортировку и поиск в массивах, работать с многомерными массивами. Мы познакомим вас с функциональным программированием, начав с лямбда-выражений (безымянных функций) и диапазонов библиотеки ranges, которая входит в «большую четверку» новых возможностей C++20. В разделе 6.15 на примере готовых объектов мы продемонстрируем векторы — контейнеры данных, основанные на шаблоне класса vector стандартной библиотеки C++. По сути, вся эта глава представляет собой большой урок работы с готовыми объектами — массивами и векторами. Примеры исходного кода в этой главе хорошо иллюстрируют современные идиомы программирования на C++.

В главе 7 «Указатели в современном C++ (фактор риска)» подробно рассматриваются указатели и объясняется тесная взаимосвязь между указателями, массивами на основе указателей и строками на основе указателей (которые также называют строками в стиле C). Все эти традиционные элементы C++ унаследовал от языка C. Указатели являются мощным инструментом программиста, но с ними сложно работать и они часто становятся причиной ошибок в программах. Поэтому мы покажем вам современные альтернативы указателям, которые сделают ваш код более надежным и безопасным: классы array и vector, класс span (C++20) и класс string_view (C++17). Но вы должны уметь работать и с традиционными указателями, чтобы читать код старых программ. Мы расскажем о тех немногих случаях, когда указатели нужны даже в новых программах. Во всех остальных случаях мы рекомендуем использовать вместо указателей современные языковые средства. К ним относится класс span, с объектами которого вы будете работать в разделе 7.10. С помощью этого класса вы сможете, не используя указатели, читать и обрабатывать элементы традиционных массивов на основе указателей, а также современных контейнеров array и vector. В этой главе мы продолжим акцентировать внимание на современных идиомах программирования на C++.

В главе 8 «Строки и их представления, текстовые файлы, CSV-файлы и регулярные выражения» вы узнаете о больших возможностях класса string стандартной библиотеки. Затем мы расскажем, как выполнять операции чтения и записи с обычными текстовыми файлами и с файлами в формате CSV, которые часто применяются для работы с наборами данных. Мы также расскажем об операциях со строками с помощью поддерживаемых стандартной библиотекой регулярных выражений. В С++ есть два типа строк: объекты класса string и традиционные строки на основе указателей. Мы используем объекты класса string, чтобы сделать программы более надежными и избежать многих проблем безопасности, свойственных традиционным строкам. В новых разработках надо отдавать предпочтение объектам класса string. Вы узнаете о классе string_view (C++17) — простом и универсальном средстве передачи строк любого типа функциям. В конце главы вы продолжите работать с готовыми объектами:

• Раздел 8.19 посвящен анализу данных. Вы прочитаете и проанализируете CSV-файл, содержащий набор данных «Титаник», — один из популярных учебных инструментов для начинающих аналитиков.

• Раздел 8.20 посвящен регулярным выражениям, которые нужны для поиска и замены фрагментов текста.

Часть 3. Объектно-ориентированное программирование

В главе 9 «Пользовательские классы» вы начнете изучать объектно-ориентированное программирование и узнаете, как создавать свои собственные классы. Язык C++ является расширяемым: каждый созданный вами класс становится новым типом данных, после чего вы можете создавать любые объекты этого типа. В разделе 9.22 вы найдете очередной пример работы с готовыми объектами: сторонняя библиотека cereal позволит вам легко выполнять сериализацию (преобразование объектов в формат JavaScript Object Notation — JSON) и десериализацию (обратное преобразование из формата JSON).

Глава 10 «ООП: наследование и динамический полиморфизм» посвящена отношениям между классами в иерархии наследования и мощным средствам динамического полиморфизма, обеспечивающим эти отношения. Из этой главы вы узнаете об основных принципах полиморфизма. Один из самых важных моментов этой главы — подробная схема, объясняющая, как полиморфизм, виртуальные функции и динамическое связывание реализованы «под капотом» языка C++. Вы увидите, что для этого используется элегантная структура данных на основе указателей. Мы расскажем и о других средствах полиморфизма, среди которых идиома невиртуального интерфейса (NVI), а также std::variant и std::visit. Вы узнаете о преимуществах наследования интерфейса перед наследованием реализации.

В главе 11 «Перегрузка операторов, семантика копирования и перемещения, умные указатели» вы узнаете, как использовать стандартные операторы языка C++ для операций с объектами пользовательских (ваших собственных) классов. Вы также познакомитесь с умными указателями и с динамическим управлением памятью. Умные указатели позволяют избежать ошибок динамического управления памятью, предоставляя программисту больше возможностей, чем традиционные указатели. Мы обсудим умные указатели класса unique_ptr. Ключевая тема этой главы — создание полноценных высококачественных классов. Мы начнем с тест-драйва класса string, который является красивым примером перегрузки операторов. Затем мы перейдем к одному из важнейших примеров книги: вы узнаете, как написать пользовательский класс контейнеров MyArray, используя перегруженные операторы и другие языковые средства таким образом, чтобы в вашем классе не было проблем, свойственных массивам на основе указателей8. Мы представим вам и реализуем пять специальных функций, которые можно определять в каждом классе: копирующий конструктор, оператор копирующего присваивания, перемещающий конструктор, оператор перемещающего присваивания и деструктор. Мы обсудим семантику копирования, а также семантику перемещения, которая позволяет компилятору быстро перемещать ресурсы из одного объекта в другой, избегая бесполезных и ресурсоемких операций копирования. Мы расскажем о новом операторе трехстороннего сравнения (<=>) и о том, как реализовать пользовательские конвертирующие операторы. В главе 15 вы усовершенствуете класс MyArray, преобразовав его в шаблон класса, позволяющий хранить данные разных типов. Вы создадите по-настоящему полезные классы.

Глава 12 «Исключения и обзор контрактного программирования» продолжает тему обработки исключений, начатую в главе 6. Мы объясним, когда нужны исключения и какие бывают гарантии безопасности исключений, рассмотрим исключения в контексте конструкторов и деструкторов, расскажем об обработке ошибок динамического выделения памяти и о том, почему в некоторых проектах исключения запрещены. Глава завершается введением в так называемые контракты, которые могут появиться в будущих версиях C++; мы расскажем о контрактах на примере их экспериментальной реализации, опубликованной на сайте godbolt.org. Благодаря контрактам программисты смогут отказаться от большинства исключений (то есть объявлять большинство функций со спецификатором noexcept), что позволит компилятору оптимизировать исполняемый код и избежать сложных ресурсоемких операций, связанных с обработкой исключений.

Часть 4. Контейнеры, итераторы и алгоритмы стандартной библиотеки

В главе 13 «Контейнеры и итераторы стандартной библиотеки» начинается более широкое и глубокое рассмотрение трех ключевых компонентов стандартной библиотеки языка C++:

• контейнеров (основанных на шаблонах структур данных);

• итераторов (необходимых для доступа к элементам контейнеров);

• алгоритмов (использующих итераторы для обработки контейнеров).

Мы обсудим контейнеры, а также адаптеры контейнеров и псевдоконтейнеры. Вы увидите, что стандартная библиотека C++ предоставляет вам готовые структуры данных, широко применяемые программистами, поэтому вам не нужно создавать свои собственные. Почти все связанные со структурами данных задачи, которые вам могут встретиться, вы сможете решить средствами стандартной библиотеки. Мы продемонстрируем большинство контейнеров стандартной библиотеки и объясним, как применять алгоритмы к различным типам контейнеров, используя итераторы. Вы увидите, что разные контейнеры поддерживают разные типы итераторов. Мы продолжим показывать те ценные возможности упрощения кода, которые дает программисту введенная в C++20 библиотека ranges.

В главе 14 «Алгоритмы стандартной библиотеки, диапазоны и представления C++20» представлены многие из 115 алгоритмов стандартной библиотеки. В цент­ре внимания — типичные операции с контейнерами, в том числе заполнение контейнеров значениями, генерация значений, сравнение элементов и целых контейнеров, удаление элементов, замена элементов, математические операции, поиск, сортировка, обмен значениями, копирование, объединение, операции со множествами, определение границ контейнеров, нахождение наименьших и наибольших значений. Мы обсудим минимальные требования к итераторам, чтобы вы знали, какие контейнеры совместимы с тем или иным алгоритмом. Мы начинаем обсуждение концептов, входящих в «большую четверку» новых возможностей C++20. Алгоритмы из пространства имен std::ranges (C++20) используют концепты, чтобы проверять корректность получаемых аргументов. Мы продолжим обсуждение функционального программирования на примере диапазонов и представлений C++20.

Часть 5. Более сложные темы

В главе 15 «Шаблоны, концепты (C++20) и метапрограммирование» рассматривается обобщенное программирование на основе шаблонов, которое применяется в C++ с момента выхода стандарта 1998 года. Роль шаблонов возрастала с каждым новым выпуском C++. Для современного C++ характерен перенос значительной части ресурсоемких операций на этап компиляции, что позволяет компилятору более надежно контролировать типы данных и повышает быстродействие во время выполнения программ. Как вы увидите, шаблоны и особенно метапрограммирование на основе шаблонов — это важнейшие средства для переноса многих операций с этапа выполнения на этап компиляции. В этой главе мы более подробно рассмотрим шаблоны, объясним, как разрабатывать ваши собственные шаблоны классов, и детально рассмотрим введенные в C++20 концепты. Вы создадите свои собственные концепты, преобразуете созданный в главе 11 класс MyArray в шаблон класса, имеющий итераторы, а также поработаете с вариативными шаблонами, которые могут принимать любое количество аргументов. Мы познакомим вас с метапрограммированием на основе шаблонов.

Глава 16 «Модули C++20: технология разработки больших программ» представляет следующую из «большой четверки» новых возможностей C++20. Модули — это новый способ структурирования кода, позволяющий вам решать, какие объявления надо открыть для клиентского кода, и предотвратить доступ извне ко всем остальным деталям реализации классов. Модули помогают программистам работать эффективнее, особенно при создании, сопровождении и модернизации больших информационных систем. Модули помогают быстрее создавать такие системы и делают их более масштабируемыми. По словам создателя C++ Бьерна Страуструпа, «модули дают языку C++ историческую возможность улучшить чистоту кода и время компиляции (перенося C++ в XXI век)». Вы увидите, что даже при разработке небольших систем модули немедленно дают преимущества, устраняя необходимость в препроцессоре C++. Мы бы с удовольствием интегрировали модули в наши программы, но на данный момент в наших основных компиляторах еще не реализована полноценная поддержка модулей.

Глава 17 «Параллельные алгоритмы и конкурентность: высокоуровневый подход» — одна из самых важных в книге. В ней представлены имеющиеся в C++ средства создания многопоточных приложений. Распределение нескольких задач между потоками процессора может значительно повышать быстродействие и скорость реакции программы. Мы показываем, как использовать готовые параллельные алгоритмы (C++17) для создания многопоточных программ, которые будут работать быстрее (как правило, намного быстрее) на современных компьютерах с многоядерными процессорами. Например, мы сортируем 100 миллионов чисел сначала последовательным, а затем параллельным алгоритмом, измеряя с помощью библиотеки <chrono> прирост производительности параллельного алгоритма на 4-ядерном и 8-ядерном процессорах. Вы увидите, что на компьютере с 64-битной версией Windows 10 и 8-ядерным процессором Intel параллельная сортировка может выполняться почти в 7 раз быстрее, чем последовательная. Мы обсуждаем взаимодействие потока-производителя и потока-потребителя, демонстрируя различные способы их синхронизации с помощью низкоуровневых и высокоуровневых средств конкурентного программирования, в том числе защелок, барьеров и семафоров, введенных в C++20. Мы объясняем, в чем заключается сложность конкурентного программирования и почему при любой возможности надо отдавать предпочтение высокоуровневым средствам конкурентности. Такие низкоуровневые средства, как семафоры и атомарные типы, имеет смысл применять для реализации средств более высокого уровня, таких как защелки.

В главе 18 «Корутины (C++20)» представлены корутины — последняя из «большой четверки» новых возможностей C++20. Корутина — это функция, которая может приостановить свое выполнение, а впоследствии возобновить его по инструкции из другой части программы. Все механизмы реализации такого поведения корутин полностью реализуются компилятором без вашего участия. Вы увидите, что корутиной является любая функция, содержащая хотя бы одно из ключевых слов co_await, co_yield или co_return, и такие функции дают вам возможность писать программы с конкурентными задачами, сохраняя простой последовательный стиль кодирования. Для поддержки корутин нужна сложная инфраструктура, которую вы теоретически могли бы написать самостоятельно, но это сложно, утомительно и чревато ошибками. Большинство экспертов сходятся во мнении, что надо использовать готовые высокоуровневые библиотеки поддержки корутин, и мы демонстрируем именно такой подход. В сообществе разработчиков открытого программного обеспечения уже созданы несколько экспериментальных библиотек для быстрой и удобной работы с корутинами. Две из них мы используем в примерах кода этой главы. Вероятно, поддержка корутин будет добавлена в стандартную библиотеку C++23.

Приложения

Приложение А «Приоритеты и группировка операторов» содержит список стандартных операторов языка C++, отсортированных по их приоритетам. В первый раздел списка включены наиболее приоритетные операторы (выполняемые первыми), в каждый последующий раздел — операторы с последовательно убывающими приоритетами.

Приложение Б «Набор символов ASCII» содержит список стандартных символов и соответствующих им чисел.


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

В главе 11 «Перегрузка операторов, семантика копирования и перемещения, умные указатели» вы узнаете, как использовать стандартные операторы языка C++ для операций с объектами пользовательских (ваших собственных) классов. Вы также познакомитесь с умными указателями и с динамическим управлением памятью. Умные указатели позволяют избежать ошибок динамического управления памятью, предоставляя программисту больше возможностей, чем традиционные указатели. Мы обсудим умные указатели класса unique_ptr. Ключевая тема этой главы — создание полноценных высококачественных классов. Мы начнем с тест-драйва класса string, который является красивым примером перегрузки операторов. Затем мы перейдем к одному из важнейших примеров книги: вы узнаете, как написать пользовательский класс контейнеров MyArray, используя перегруженные операторы и другие языковые средства таким образом, чтобы в вашем классе не было проблем, свойственных массивам на основе указателей8. Мы представим вам и реализуем пять специальных функций, которые можно определять в каждом классе: копирующий конструктор, оператор копирующего присваивания, перемещающий конструктор, оператор перемещающего присваивания и деструктор. Мы обсудим семантику копирования, а также семантику перемещения, которая позволяет компилятору быстро перемещать ресурсы из одного объекта в другой, избегая бесполезных и ресурсоемких операций копирования. Мы расскажем о новом операторе трехстороннего сравнения (<=>) и о том, как реализовать пользовательские конвертирующие операторы. В главе 15 вы усовершенствуете класс MyArray, преобразовав его в шаблон класса, позволяющий хранить данные разных типов. Вы создадите по-настоящему полезные классы.

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