Fedor G. Pikus
Hands-On Design Patterns
with C++
Solve common C++ problems with modern design patterns
and build robust applications
BIRMINGHAM – MUMBAI
Стр.3
Федор Г. Пикус
Идиомы и паттерны
проектирования
в современном C++
Применение современных паттернов проектирования
к решению типичных задач на C++ для построения
надежных приложений
Москва, 2020
Стр.4
УДК 004.4
ББК 32.973.202-018.2
П32
П32 Идиомы и паттерны проектирования в современном C++ / пер. с анг.
А. А. Слинкина. – М.: ДМК Пресс, 2020. – 452 с.: ил.
Пикус Ф. Г.
ISBN 978-5-97060-786-2
В книге акцент сделан на паттерны проектирования, которые отвечают естественным
нуждам программиста на С++, а также паттернам, выигрывающим от уникальных особенностей
С++, в частности, обощенного программирования. Вооруженные знанием этих
паттернов, вы будете тратить меньше времени на поиск решения конкретной задачи
и познакомитесь с решениями, доставшимися тяжким опытом других разработчиков,
их достоинствами и недостатками.
Издание предназначено программистам на С++, хорошо владеющих средствами
и синтаксисом языка.
УДК 004.4
ББК 32.973.202-018.2
Authorized Russian translation of the English edition of Hands-On Design Patterns with C++
ISBN 9781788832564 © 2019 Packt Publishing.
This translation is published and sold by permission of Packt Publishing, which owns or
controls all rights to publish and sell the same.
Все права защищены. Любая часть этой книги не может быть воспроизведена в какой
бы то ни было форме и какими бы то ни было средствами без письменного разрешения
владельцев авторских прав.
ISBN 978-1-78883-256-4 (анг.)
ISBN 978-5-97060-786-2 (рус.)
© 2019 Packt Publishing
© Оформление, издание, перевод, ДМК Пресс, 2020
Стр.5
Содержание
Об авторе ............................................................................................................12
О рецензенте ......................................................................................................13
Предисловие ......................................................................................................14
Глава 1. Введение в наследование и полиморфизм ...............................20
Классы и объекты..................................................................................................20
Наследование и иерархии классов ......................................................................22
Полиморфизм и виртуальные функции .............................................................27
Множественное наследование .............................................................................31
Резюме ...................................................................................................................33
Вопросы .................................................................................................................33
Для дальнейшего чтения ......................................................................................33
Глава 2. Шаблоны классов и функций .........................................................34
Шаблоны в C++ ......................................................................................................34
Шаблоны функций ............................................................................................35
Шаблоны классов ..............................................................................................35
Шаблоны переменных ......................................................................................36
Параметры шаблонов, не являющиеся типами ..............................................36
Конкретизация шаблона ......................................................................................37
Шаблоны функций ............................................................................................38
Шаблоны классов ..............................................................................................41
Специализация шаблона ......................................................................................42
Явная специализация .......................................................................................43
Частичная специализация ...............................................................................44
Перегрузка шаблонных функций ........................................................................47
Шаблоны с переменным числом аргументов .....................................................50
Лямбда-выражения ..............................................................................................54
Резюме ...................................................................................................................58
Вопросы .................................................................................................................58
Для дальнейшего чтения ......................................................................................58
Глава 3. Владение памятью ............................................................................59
Технические требования ......................................................................................59
Что такое владение памятью? .............................................................................59
Правильно спроектированное владение памятью ........................................60
Стр.6
6 Содержание
Плохо спроектированное владение памятью.................................................61
Выражение владения памятью в C++ ..................................................................62
Выражения невладения ...................................................................................63
Выражение монопольного владения ..............................................................64
Выражение передачи монопольного владения ..............................................65
Выражение совместного владения ..................................................................66
Резюме ...................................................................................................................68
Вопросы .................................................................................................................68
Для дальнейшего чтения ......................................................................................69
Глава 4. От простого к нетривиальному ......................................................70
Технические требования ......................................................................................70
Обмен и стандартная библиотека шаблонов ......................................................70
Обмен и контейнеры STL .................................................................................71
Свободная функция swap .................................................................................73
Обмен как в стандарте .....................................................................................74
Когда и для чего использовать обмен .................................................................75
Обмен и безопасность относительно исключений ........................................75
Другие распространенные идиомы обмена ...................................................77
Как правильно реализовать и использовать обмен ...........................................78
Реализация обмена ...........................................................................................78
Правильное использование обмена ................................................................82
Глава 5. Все о захвате ресурсов как инициализации ..............................85
Технические требования ......................................................................................85
Управление ресурсами в C++ ...............................................................................86
Установка библиотеки эталонного микротестирования ...............................86
Установка Google Test .......................................................................................87
Подсчет ресурсов ..............................................................................................87
Опасности ручного управления ресурсами ........................................................88
Ручное управление ресурсами чревато ошибками ........................................88
Управление ресурсами и безопасность относительно исключений .............91
Идиома RAII ..........................................................................................................93
RAII в двух словах .............................................................................................93
RAII для других ресурсов ..................................................................................97
Досрочное освобождение .................................................................................98
Аккуратная реализация RAII-объектов ........................................................101
Недостатки RAII ..............................................................................................104
Резюме ...................................................................................................................83
Вопросы .................................................................................................................84
Резюме .................................................................................................................106
Вопросы ...............................................................................................................106
Для дальнейшего чтения ....................................................................................107
Стр.7
Содержание 7
Глава 6. Что такое стирание типа ................................................................108
Технические требования ....................................................................................108
Что такое стирание типа? ...................................................................................108
Стирание типа на примере ............................................................................109
Как стирание типа реализовано в C++? .............................................................112
Очень старый способ стирания типа.............................................................112
Объектно-ориентированное стирание типа ................................................113
Противоположность стиранию типа .............................................................116
Стирание типа в C++ .......................................................................................117
Когда использовать стирание типа, а когда избегать его ................................119
Стирание типа и проектирование программ ...............................................119
Установка библиотеки эталонного микротестирования .............................121
Издержки стирания типа ...............................................................................121
Резюме .................................................................................................................123
Вопросы ...............................................................................................................124
Глава 7. SFINAE и управление разрешением перегрузки .....................125
Технические требования ....................................................................................125
Разрешение перегрузки и множество перегруженных вариантов .................125
Перегрузка функций в C++ .............................................................................126
Шаблонные функции ......................................................................................129
Подстановка типов в шаблонных функциях .....................................................131
Выведение и подстановка типов ...................................................................132
Неудавшаяся подстановка .............................................................................133
Неудавшаяся подстановка – не ошибка ........................................................135
Управление разрешением перегрузки ..............................................................137
Простое применение SFINAE .........................................................................138
Продвинутое применение SFINAE ................................................................140
Еще раз о продвинутом применении SFINAE ..............................................150
SFINAE без компромиссов .............................................................................155
Резюме .................................................................................................................160
Вопросы ...............................................................................................................161
Для дальнейшего чтения ....................................................................................161
Глава 8. Рекурсивный шаблон .....................................................................162
Технические требования ....................................................................................162
Укладываем CRTP в голове.................................................................................162
Что не так с виртуальной функцией? ............................................................163
Введение в CRTP .............................................................................................165
CRTP и статический полиморфизм ...................................................................168
Полиморфизм времени компиляции ...........................................................168
Чисто виртуальная функция времени компиляции ....................................170
Деструкторы и полиморфное удаление ........................................................171
Стр.8
8 Содержание
CRTP и управление доступом ........................................................................173
CRTP как паттерн делегирования ......................................................................174
Расширение интерфейса ................................................................................175
Глава 9. Именованные аргументы и сцепление методов ....................181
Технические требования ....................................................................................181
Проблема аргументов .........................................................................................181
Что плохого в большом количестве аргументов? .........................................182
Агрегатные параметры ..................................................................................185
Именованные аргументы в C++ .........................................................................187
Сцепление методов ........................................................................................188
Сцепление методов и именованные аргументы ..........................................188
Производительность идиомы именованных аргументов ...........................191
Сцепление методов в общем случае .................................................................194
Сцепление и каскадирование методов .........................................................194
Сцепление методов в общем случае .............................................................195
Сцепление методов в иерархиях классов .....................................................196
Резюме .................................................................................................................198
Вопросы ...............................................................................................................199
Глава 10. Оптимизация локального буфера.............................................200
Технические требования ....................................................................................200
Издержки выделения небольших блоков памяти ............................................200
Стоимость выделения памяти .......................................................................201
Введение в оптимизацию локального буфера ..................................................204
Основная идея ................................................................................................204
Эффект оптимизации локального буфера ....................................................206
Дополнительные оптимизации .....................................................................209
Оптимизация локального буфера в общем случае...........................................209
Короткий вектор .............................................................................................210
Объекты со стертым типом и вызываемые объекты ...................................212
Оптимизация локального буфера в библиотеке C++ ...................................215
Резюме .................................................................................................................180
Вопросы ...............................................................................................................180
Недостатки оптимизации локального буфера .................................................216
Резюме .................................................................................................................217
Вопросы ...............................................................................................................217
Для дальнейшего чтения ....................................................................................217
Глава 11. Охрана области видимости ........................................................218
Технические требования ....................................................................................218
Обработка ошибок и идиома RAII .....................................................................219
Безопасность относительно ошибок и исключений ....................................219
Захват ресурса есть инициализация .............................................................222
Стр.9
Содержание 9
Паттерн ScopeGuard ............................................................................................225
Основы ScopeGuard ........................................................................................226
ScopeGuard в общем виде ...............................................................................231
ScopeGuard и исключения ..................................................................................236
Что не должно возбуждать исключения ............................................................236
ScopeGuard, управляемый исключениями....................................................239
ScopeGuard со стертым типом ...........................................................................243
Резюме .................................................................................................................246
Вопросы ...............................................................................................................246
Глава 12. Фабрика друзей .............................................................................247
Технические требования ....................................................................................247
Друзья в C++ ........................................................................................................247
Как предоставить дружественный доступ в C++ ..........................................247
Друзья и функции-члены ...............................................................................248
Друзья и шаблоны ...............................................................................................252
Друзья шаблонов классов ...............................................................................252
Фабрика друзей шаблона ...................................................................................255
Генерация друзей по запросу ........................................................................255
Фабрика друзей и Рекурсивный шаблон ...........................................................257
Резюме .................................................................................................................259
Вопросы ...............................................................................................................260
Глава 13. Виртуальные конструкторы и фабрики ..................................261
Технические требования ....................................................................................261
Почему конструкторы не могут быть виртуальными ......................................261
Когда объект получает свой тип? ...................................................................262
Паттерн Фабрика ................................................................................................265
Основа паттерна Фабричный метод .............................................................265
Фабричные методы с аргументами ...............................................................266
Динамический реестр типов .........................................................................267
Полиморфная фабрика ...................................................................................270
Похожие на Фабрику паттерны в C++................................................................272
Полиморфное копирование ...........................................................................272
CRTP-фабрика и возвращаемые типы ..........................................................273
CRTP-фабрика с меньшим объемом копирования и вставки .....................274
Резюме .................................................................................................................276
Вопросы ...............................................................................................................277
Глава 14. Паттерн Шаблонный метод и идиома
невиртуального интерфейса ........................................................................278
Технические требования ....................................................................................278
Паттерн Шаблонный метод ...............................................................................279
Стр.10
10 Содержание
Шаблонный метод в C++ ................................................................................279
Применения Шаблонного метода .................................................................280
Предусловия, постусловия и действия ..........................................................282
Невиртуальный интерфейс ................................................................................283
Виртуальные функции и контроль доступа ..................................................283
Идиома NVI в C++ ...........................................................................................285
Замечание о деструкторах .............................................................................287
Недостатки невиртуального интерфейса .........................................................288
Компонуемость ...............................................................................................288
Проблема хрупкого базового класса .............................................................289
Резюме .................................................................................................................291
Вопросы ...............................................................................................................291
Для дальнейшего чтения ....................................................................................291
Глава 15. Одиночка – классический
объектно-ориентированный паттерн ........................................................292
Технические требования ....................................................................................292
Паттерн Одиночка – для чего он предназначен, а для чего – нет ...................292
Что такое Одиночка? ......................................................................................293
Когда использовать паттерн Одиночка .........................................................294
Типы Одиночек ...................................................................................................297
Статический Одиночка ..................................................................................299
Одиночка Мейерса ..........................................................................................301
Утекающие Одиночки ....................................................................................308
Глава 16. Проектирование на основе политик ........................................312
Технические требования ....................................................................................312
Паттерн Стратегия и проектирование на основе политик ..............................312
Основы проектирования на основе политик ...............................................313
Реализация политик .......................................................................................319
Использование объектов политик .................................................................322
Продвинутое проектирование на основе политик ..........................................329
Политики для конструкторов ........................................................................329
Применение политик для тестирования ......................................................337
Адаптеры и псевдонимы политик.................................................................339
Применение политик для управления открытым интерфейсом ................341
Перепривязка политики ................................................................................347
Резюме .................................................................................................................310
Вопросы ...............................................................................................................311
Рекомендации и указания .................................................................................349
Достоинства проектирования на основе политик .......................................349
Недостатки проектирования на основе политик .........................................350
Рекомендации по проектированию на основе политик ..............................352
Стр.11
Содержание 11
Почти политики ..................................................................................................354
Резюме .................................................................................................................360
Вопросы ...............................................................................................................361
Глава 17. Адаптеры и Декораторы ..............................................................362
Технические требования ....................................................................................362
Паттерн Декоратор .............................................................................................362
Основной паттерн Декоратор ........................................................................363
Декораторы на манер C++ ..............................................................................366
Полиморфные декораторы и их ограничения .............................................371
Компонуемые декораторы .............................................................................373
Паттерн Адаптер .................................................................................................375
Основной паттерн Адаптер ...........................................................................375
Адаптеры функций .........................................................................................378
Адаптеры времени компиляции ...................................................................381
Адаптер и Политика ...........................................................................................384
Резюме .................................................................................................................388
Вопросы ...............................................................................................................389
Глава18. Паттерн Посетитель и множественная
диспетчеризация .............................................................................................390
Технические требования ....................................................................................390
Паттерн Посетитель ............................................................................................391
Что такое паттерн Посетитель? .....................................................................391
Простой Посетитель на C++ ...........................................................................393
Обобщения и ограничения паттерна Посетитель ........................................397
Посещение сложных объектов ...........................................................................401
Посещение составных объектов ....................................................................401
Сериализация и десериализация с помощью Посетителя ..........................403
Ациклический посетитель .................................................................................409
Посетители в современном C++ .........................................................................412
Обобщенный посетитель ...............................................................................412
Лямбда-посетитель .........................................................................................414
Обобщенный Ациклический посетитель ......................................................418
Посетитель времени компиляции .....................................................................421
Резюме .................................................................................................................427
Вопросы ...............................................................................................................428
Ответы на вопросы .........................................................................................429
Предметный указатель ..................................................................................448
Стр.12