Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Скользкие места С++. Как избежать проблем при проектировании и компиляции ваших программ

Покупка
Артикул: 615986.01.99
К покупке доступен более свежий выпуск Перейти
Вы держите в руках руководство по тому, как не допускать и исправлять 99% типичных, разрушительных и просто любопытных ошибок при проектировании и реализации программ на языке C++. Эту книгу можно рассматривать также, как взгляд посвященного на нетривиальные особенности и приемы программирования на C++. Обсуждаются как наиболее распространенные «ляпы», имеющиеся почти в любой программе на C++, так и сложные ошибки в использовании синтаксиса, препроцессора, преобразований типов, инициализации, управления памятью и ресурсами, полиморфизма, а также при проектировании классов и иерархий. Все ошибки и их последствия обсуждаются в контексте. Подробно описываются способы разрешения указанных проблем. Автор знакомит читателей с идиомами и паттернами проектирования, с помощью которых можно решать типовые задачи. Читатель также узнает много нового о плохо понимаемых возможностях C++, которые применяются в продвинутых программах и проектах. На сайте http://www.semantics.org можно найти полный код примеров из книги. В книге рассказывается, как миновать наиболее серьезные опасности, подстерегающие программиста на C++. Программисты найдут в ней практические рекомендации, которые позволят им стать настоящими экспертами. Издание предназначено для всех программистов, желающих научиться писать правильные и корректно работающие программы на языке С++.
Дьюхэрст, Стефан, К. Скользкие места С++. Как избежать проблем при проектировании и компиляции ваших программ [Электронный ресурс] / Стефан К. Дьюхэрст. - Москва : ДМК Пресс, 2009. - 264 с.: ил. - ISBN 5-94074-083-9. - Текст : электронный. - URL: https://znanium.com/catalog/product/407742 (дата обращения: 29.03.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов. Для полноценной работы с документом, пожалуйста, перейдите в ридер.
Стефан К. Дьюхэрст

Скользкие места C++

Как избежать проблем
при проектировании и компиляции
ваших программ

C++ Gotchas

Avoiding Common Problems
in Coding and Design

Stephen C. Dewhurst

AddisonWesley

Boston • San Francisco • New York • Toronto • Montreal
London • Munich • Paris • Madrid
Capetown • Sydney • Tokyo • Singapore • Mexico City

Cкользкие места C++

Как избежать проблем
при проектировании и компиляции
ваших программ

Стефан К. Дьюхэрст

Москва

УДК 004.4
ББК 32.973.26018.2
Д92

Стефан К. Дьюхэрст
Д92
Скользкие места С++. Как избежать проблем при проектировании и компиляции ваших программ. – М.: ДМК Пресс. – 264 с.: ил.

ISBN 5940740839

УДК 004.4
ББК 32.973.26018.2

Original English language edition published by Pearson Education, Inc. Copyright © 2003
by Syngress Publishing, Inc. All rights reserved.

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

ISBN 0-321-12518-5 (àíãë.)
Copyright © by Pearson Education, Inc.
ISBN 5-94074-083-9
© Ïåðåâîä íà ðóññêèé ÿçûê, îôîðìëåíèå, èçäàíèå
Èçäàòåëüñòâî ÄÌÊ-ïðåññ

Вы держите в руках руководство по тому, как не допускать и исправлять 99% типичных, разрушительных и просто любопытных ошибок при проектировании и реализации программ на языке C++. Эту книгу можно рассматривать также, как взгляд посвященного на нетривиальные особенности и приемы программирования на C++.
Обсуждаются как наиболее распространенные «ляпы», имеющиеся почти в любой программе на C++, так и сложные ошибки в использовании синтаксиса, препроцессора, преобразований типов, инициализации, управления памятью и ресурсами, полиморфизма, а также при проектировании классов и иерархий. Все ошибки
и их последствия обсуждаются в контексте. Подробно описываются способы разрешения указанных проблем.
Автор знакомит читателей с идиомами и паттернами проектирования, с помощью которых можно решать типовые задачи. Читатель также узнает много нового
о плохо понимаемых возможностях C++, которые применяются в продвинутых
программах и проектах. На сайте http://www.semantics.org можно найти полный
код примеров из книги.
В книге рассказывается, как миновать наиболее серьезные опасности, подстерегающие программиста на C++. Программисты найдут в ней практические рекомендации, которые позволят им стать настоящими экспертами.
Издание предназначено для всех программистов, желающих научиться писать
правильные и корректно работающие программы на языке С++.

Содержание

Предисловие .......................................................................................... 9
Благодарности ..................................................................................... 13
Глава 1. Основы
Совет 1. Избыточное комментирование ............................................... 15
Совет 2. Магические числа................................................................... 17
Совет 3. Глобальные переменные ........................................................ 19
Совет 4. Отличайте перегрузку от инициализации аргументов
по умолчанию ....................................................................................... 21
Совет 5. О неправильной интерпретации ссылок ................................. 22
Совет 6. О неправильной интерпретации const .................................... 25
Совет 7. Не забывайте о тонкостях базового языка.............................. 26
Совет 8. Отличайте доступность от видимости .................................... 29
Совет 9. О неграмотности .................................................................... 33
Лексика ........................................................................................... 33
Нулевые указатели .......................................................................... 34
Акронимы ........................................................................................ 35
Совет 10. Не игнорируйте идиомы ....................................................... 35
Совет 11. Не мудрствуйте лукаво ......................................................... 38
Совет 12. Не ведите себя как дети ....................................................... 40

Глава 2. Синтаксис

Совет 13. Не путайте массивы с инициализаторами ............................ 42
Совет 14. Неопределенный порядок вычислений ................................. 43
Порядок вычисления аргументов функции ...................................... 43
Порядок вычисления подвыражений ............................................... 44
Порядок вычисления размещающего new ....................................... 45
Операторы, которые фиксируют порядок вычислений .................... 46
Некорректная перегрузка операторов............................................. 47
Совет 15. Помните о предшествовании ............................................... 47
Приоритеты и ассоциативность....................................................... 47
Проблемы, связанные с приоритетом операторов .......................... 48
Проблемы, связанные с ассоциативностью ..................................... 49
Совет 16. Подводные камни в предложении for .................................... 50
Совет 17. Принцип «максимального куска» .......................................... 53

Содержание
Содержание
Содержание
Содержание
Содержание

Совет 18. О порядке следования спецификаторов в объявлениях........ 54
Совет 19. Функция или объект? ............................................................ 55
Совет 20. Перестановка квалификаторов типа..................................... 55
Совет 21. Автоинициализация .............................................................. 56
Совет 22. Статические и внешние типы ................................................ 58
Совет 23. Аномалия при поиске операторной функции ........................ 58
Совет 24. Тонкости оператора > ......................................................... 60

Глава 3. Препроцессор

Совет 25. Определение литералов с помощью #define ........................ 62
Совет 26. Определение псевдофункций с помощью #define ................ 64
Совет 27. Не увлекайтесь использованием директивы #if .................... 66
Использование директивы #if для отладки ...................................... 66
Использование #if для переносимости ............................................ 68
А как насчет классов? ...................................................................... 69
Практика – критерий истины ........................................................... 70
Совет 28. Побочные эффекты в утверждениях ..................................... 70

Глава 4. Преобразования

Совет 29. Преобразование посредством void * .................................... 73
Совет 30. Срезка .................................................................................. 76
Совет 31. Преобразование в указатель на константу ........................... 78
Совет 32. Преобразование в указатель на указатель на константу ....... 79
Совет 33. Преобразование указателя на указатель на базовый класс .... 82
Совет 34. Проблемы с указателем на многомерный массив................. 82
Совет 35. Бесконтрольное понижающее приведение........................... 84
Совет 36. Неправильное использование операторов преобразования .. 84
Совет 37. Непреднамеренное преобразование с помощью
конструктора........................................................................................ 88
Совет 38. Приведение типов в случае множественного наследования ... 91
Совет 39. Приведение неполных типов ................................................ 92
Совет 40. Приведения в старом стиле .................................................. 93
Совет 41. Статические приведения ...................................................... 94
Совет 42. Инициализация формальных аргументов
временными объектами ....................................................................... 97
Совет 43. Время жизни временных объектов ..................................... 100
Совет 44. Ссылки и временные объекты............................................. 101
Совет 45. Неоднозначность при использовании dynamic_cast ........... 104
Совет 46. Контравариантность........................................................... 108

Глава 5. Инициализация

Совет 47. Не путайте инициализацию и присваивание ....................... 111

Содержание
Содержание
Содержание
Содержание
Содержание

Совет 48. Правильно выбирайте область видимости переменной ..... 114
Совет 49. Внимательно относитесь к операциям копирования .......... 116
Совет 50. Побитовое копирование объектов классов......................... 119
Совет 51. Не путайте инициализацию и присваивание
в конструкторах.................................................................................. 121
Совет 52. Несогласованный порядок членов в списке инициализации ... 123
Совет 53. Инициализация виртуальных базовых классов ................... 124
Совет 54. Инициализация базового класса
в конструкторе копирования .............................................................. 128
Совет 55. Порядок инициализации статических данных
во время выполнения ......................................................................... 131
Совет 56. Прямая инициализация и инициализация копированием ... 133
Совет 57. Прямая инициализация аргументов ................................... 136
Совет 58. Что такое оптимизация возвращаемого значения? ............ 137
Совет 59. Инициализация статических членов в конструкторе ........... 141

Глава 6. Управление памятью и ресурсами

Совет 60. Различайте выделение и освобождение памяти
для скаляров и для массивов ............................................................. 143
Совет 61. Контроль ошибок при выделении памяти ........................... 146
Совет 62. Подмена глобальных new и delete ....................................... 148
Совет 63. Об области видимости и активации функцийчленов new
и delete ............................................................................................... 150
Совет 64. Строковые литералы в выражении throw ............................ 151
Совет 65. Обрабатывайте исключения правильно .............................. 154
Совет 66. Внимательно относитесь к адресам локальных объектов ... 157
Исчезающие фреймы стека ........................................................... 157
Затирание статических переменных .............................................. 158
Идиоматические трудности ........................................................... 159
Проблемы локальной области видимости ..................................... 159
Исправление ошибки путем добавления static............................... 160
Совет 67. Помните, что захват ресурса есть инициализация .............. 161
Совет 68. Правильно используйте auto_ptr......................................... 164

Глава 7. Полиморфизм

Совет 69. Кодирование типов ............................................................ 168
Совет 70. Невиртуальный деструктор базового класса ...................... 172
Неопределенное поведение .......................................................... 172
Виртуальные статические функциичлены ..................................... 173
Всех обманем ................................................................................ 174
Исключения из правил ................................................................... 175
Совет 71. Сокрытие невиртуальных функций ..................................... 176
Совет 72. Не делайте шаблонные методы слишком гибкими ............... 179
Совет 73. Перегрузка виртуальных функций ...................................... 180

Содержание
Содержание
Содержание
Содержание
Содержание

Совет 74. Виртуальные функции с аргументами по умолчанию ............... 181
Совет 75. Вызовы виртуальных функций из конструкторов
и деструкторов................................................................................... 183
Совет 76. Виртуальное присваивание ................................................ 185
Совет 77. Различайте перегрузку, переопределение и сокрытие ....... 187
Совет 78. О реализации виртуальных функций
и механизма переопределения .......................................................... 192
Совет 79. Вопросы доминирования ................................................... 197

Глава 8. Проектирование классов

Совет 80. Интерфейсы get/set............................................................ 201
Совет 81. Константные и ссылочные данныечлены ........................... 204
Совет 82. В чем смысл константных функцийчленов? ....................... 206
Синтаксис...................................................................................... 206
Простая семантика и механизм работы ......................................... 207
Семантика константной функциичлена ........................................ 208
Совет 83. Различайте агрегирование и использование ...................... 210
Совет 84. Не злоупотребляйте перегрузкой операторов .................... 214
Совет 85. Приоритеты и перегрузка ................................................... 216
Совет 86. Операторы, являющиеся членами
и друзьями класса .............................................................................. 217
Совет 87. Проблемы инкремента и декремента ................................. 218
Совет 88. Неправильная интерпретация шаблонных операций
копирования ...................................................................................... 221

Глава 9. Проектирование иерархий

Совет 89. Массивы объектов класса .................................................. 224
Совет 90. Не всегда один контейнер можно подставить
вместо другого................................................................................... 226
Совет 91. Что такое защищенный доступ? ......................................... 229
Совет 92. Применение открытого наследования
для повторного использования кода .................................................. 232
Совет 93. Конкретные открытые базовые классы ............................... 235
Совет 94. Не пренебрегайте вырожденными иерархиями .................. 236
Совет 95. Не злоупотребляйте наследованием .................................. 237
Совет 96. Управление на основе типов............................................... 240
Совет 97. Космические иерархии ....................................................... 242
Совет 98. Задание «интимных» вопросов объекту .............................. 244
Совет 99. Опрос возможностей.......................................................... 248
Список литературы ........................................................................... 252
Предметный указатель .................................................................... 253

Предисловие

Эта книга – результат почти двадцатилетней работы, полной мелких разочарований, серьезных ошибок, бессонных ночей и выходных, добровольно проведенных за клавиатурой компьютера. Я включил в нее 99 глав, в которых описываются «скользкие места» (gotcha) в языке C++, которые иногда являются
источниками распространенных ошибок и путаницы, а иногда просто вызывают
интерес. С большинством из них я сталкивался лично (как это ни печально).
У слова «gotcha» довольно туманная история и множество определений.
В этой книге мы будем понимать под ним типичную проблему, возникающую при
проектировании и программировании на языке C++, которую можно предотвратить. В книге описаны самые разные проблемы такого рода: мелкие синтаксические тонкости, серьезные огрехи при проектировании и поведение, которое противно всем «нормам общежития».
Почти десять лет, как я начал включать замечания об отдельных скользких
местах в материалы курса по C++, который я читаю. Мне казалось, что, обращая
внимание студентов на типичные ошибки и просчеты, и одновременно показывая,
как следует решать задачу правильно, я буду способствовать тому, что новые поколения программистов на C++ не станут повторять грехов своих предшественников. В общем и целом, эта идея оказалась удачной, и меня попросили подготовить собрание взаимосвязанных скользких мест для презентации на конференциях.
Презентации завоевали популярность (не я один такой?), в результате чего я получил предложение написать книгу на эту тему.
Когда заходит речь о том, как не поскользнуться при работе с C++ или исправить последствия ошибки, нельзя не затронуть такие смежные вопросы, как наиболее распространенные паттерны проектирования, идиомы и технические детали языка.
Эта книга не о паттернах проектирования, но мы часто будем ссылаться на
них как на средство обойти скользкое место. Названия паттернов по традиции
принято писать с большой буквы, например: Template Method (Шаблонный Метод) или Bridge (Мост). При упоминании паттерна мы вкратце опишем его суть,
если это не слишком сложно, но за подробным обсуждением отсылаем к работам,
специально посвященным паттернам. Более полное описание конкретных паттернов, равно как и глубокое обсуждение этой темы в общем, можно найти в книге
Эриха Гаммы и др. «Design patterns»*. Описания паттернов Acyclic Visitor (Ациклический ациклический Посетительпосетитель), Monostate (Моносостояниемоносостояние) и Null Object (Пустой пустой Объектобъект) можно найти в книге

* Имеется русский перевод: Гамма и др. «Паттерны проектирования». (Прим. перев.)

10
10
10
10
Предисловие
Предисловие
Предисловие
Предисловие
Предисловие

Robert Martin «Agile Software Development» («Разработка программ с удовольствием»).
С точки зрения скользких мест, у паттернов проектирования есть два важных
свойства. Вопервых, каждый паттерн – это описание апробированной, неизменно приносящей успех техники проектирования, которую можно адаптировать под
конкретные условия, возникающие при решении новых задач. Вовторых, и это
даже более важно, само упоминание о том, что в приложении используется тот
или иной паттерн, документирует не только примененную технику, но также причины и результаты ее применения.
Например, если мы видим, что при проектировании программы был использован паттерн Bridge, то сразу понимаем, что реализация абстрактного типа данных
разбита на интерфейсный класс и класс реализации. Кроме того, мы знаем, что
сделано это было для того, чтобы разорвать связь между интерфейсом и реализацией, в результате чего изменение реализации никак не затронет пользователей
интерфейса. Знаем мы и то, какие накладные расходы во время выполнения влечет за собой такое разделение, как организован исходный код, реализующий абстрактный тип данных, и целый ряд других деталей. Название паттерна – это недвусмысленная ссылка на кладезь информации и опыта, стоящий за соответствующей
техникой. Обдуманное и правильное применение паттернов и связанной с ними
терминологии при проектировании и документировании программ помогает понять код и не споткнуться на скользком месте.
C++ — это сложный язык программирования, а чем сложнее язык, тем важнее
употребление идиом. В контексте языка программирования под идиомой понимается широко распространенная и имеющая всем понятный смысл комбинация
низкоуровневых языковых средств, приводящая к появлению высокоуровневой
конструкции. Такова же роль паттернов в проектировании программ. Поэтому мы
и можем говорить об операциях копирования, функциональных объектах, интеллектуальных указателях и возбуждении исключений в C++, не опускаясь до уровня деталей реализации.
Важно подчеркнуть, что идиома — это не просто известная комбинация языковых средств, но и определенные ожидания относительно того, как эта комбинация
будет себя вести. Каков смысл операции копирования? Чего ожидать в случае возбуждения исключения? Многие советы в этой книге касаются распознавания
идиом и их использования в проектировании и кодировании. Можно сказать и
так: многие из описанных скользких мест — не что иное, как игнорирование какойто идиомы C++, а для решения проблемы часто всегото и нужно, что следовать подходящей идиоме (см. «Совет 10»).
Немало глав в этой книге посвящено описанию некоторых нюансов языка,
которые часто понимают неправильно, что и приводит к проблемам. Хотя некоторые примеры могут показаться надуманными, но незнание соответствующего материала не позволит вам стать настоящим экспертом по C++. Эти «закоулки»
сами по себе могли бы стать предметом весьма любопытных и полезных исследований. Существуют они в C++ не без причины, а опытные программисты нередко
прибегают к ним при разработке нетривиальных приложений.

11
11
11
11
Предисловие
Предисловие
Предисловие
Предисловие
Предисловие

Между «скользкими местами» и паттернами проектирования можно провести
и еще одну аналогию: важность изложения предмета на сравнительно простых
примерах. Простые паттерны очень важны. В некотором смысле они даже важнее
технически более трудных паттернов, поскольку выше вероятность их широкого
применения.
Точно также, описанные в этой книге скользкие места сильно разнятся по
сложности: от простого увещевания действовать как ответственные профессионалы (см. «Совет 12») до предупреждения избегать неверной интерпретации правила
доминирования при виртуальном наследовании (см. «Совет 79»). Но по аналогии
с паттернами, в повседневной практике призыву подходить к делу ответственно
скорее найдется место, нежели правилу доминирования.
Через всю книгу красной нитью проходят две темы. Первая – это исключительная важность соглашений. Особенно актуально это для такого сложного языка, как C++. Следование принятым соглашениям позволяет эффективно и точно
доносить свои мысли до других людей. Вторая тема – это осознание того факта,
что написанный нами код комуто предстоит сопровождать. Сопровождение может быть прямым (и тогда наша программа должна быть понятна компетентному
специалисту), или косвенным и (в этом случае нужно быть уверенным, что код
останется правильным, даже если его поведение будет модифицировано в результате изменений, которые будут внесены в отдаленном будущем).
Настоящая книга построена в виде собрания коротких эссе, в каждом из которых описывается одна или несколько взаимосвязанных проблем и даются советы,
как избежать их или устранить последствия. Я не уверен, что можно написать
внутренне целостную книгу на эту тему в силу «анархической» природы материала. Тем не менее, материал разбит на главы в соответствии с общей природой
проблем или областями, в которых они обычно встречаются.
Кроме того, при обсуждении одного скользкого места неизбежно приходится
затрагивать и другие. Когда это имеет смысл, то есть практически всегда, я даю
прямые отсылки. Связность изложения внутри одной темы иногда также оказывается под вопросом. Часто, прежде чем переходить к описанию проблемы, нужно
представить контекст, в котором она проявляется. А это, в свою очередь, влечет за
собой обсуждение какойто техники, идиомы, паттерна или нюанса языка и может
далеко увести от темы раздела. Я старался свести такое «растекание мыслию по
древу» к минимуму, но, думается, было бы нечестно отказаться от него полностью. Для эффективного программирования на C++ нужно осознанно применять
знания из таких разных областей, что практически невозможно вообразить, как
исследовать этиологию этого процесса, не прибегая к подобным эклектичным
рассуждениям.
Разумеется, вовсе не обязательно – и даже не рекомендуется – читать эту книгу подряд, от «Совета 1» к «Совету 99». Прием лекарства в таких дозах может
навеки отвратить вас от программирования на C++. Гораздо лучше начать с того
места, на котором вам уже случалось поскользнуться, или с того, которое кажется
вам интересным, а потом следовать по ссылкам. А можно вообще читать в случайном порядке.

12
12
12
12
Предисловие
Предисловие
Предисловие
Предисловие
Предисловие

В тексте применяется ряд типографских эффектов, призванных облегчить усвоение материала. Вопервых, неправильный или не рекомендуемый код напечатан на сером фоне, а правильный – на белом. Вовторых, приведенный в тексте
код для краткости и ясности слегка отредактирован. Поэтому примеры не
будут компилироваться без дополнительного кода. Исходный код для нетривиальных примеров можно скачать с сайта автора по адресу www.semantics.org.
Для таких случаев в тексте приводится сокращенный путь, например: gotcha00/
somecode.cpp.
И напоследок одно предостережение: чего ни в коем случае не следует делать
со «скользкими местами», так это повышать их в статусе до идиом или паттернов.
Один из признаков правильного использования паттерна или идиомы состоит
в том, что идея ее применения в данном контексте возникает подсознательно,
спонтанно.
Распознавание же скользкого места можно уподобить условному рефлексу на
опасность: обжегшись на молоке, дуешь на воду. Но, как и в случае спичек и огнестрельного оружия, совершенно необязательно обжигаться или получать рану
в голову самому, чтобы научиться распознавать опасности опасность и сторониться ее. Обычно бывает достаточно предупреждения. Считайте эту книгу
средством прямо смотреть в глаза опасностям, подстерегающим вас в темных закоулках C++.

Стефан К. Дьюхэрст
Карвер, Массачусетс
июль 2002

Благодарности

Редакторы часто удостаиваются лишь краткого упоминания в благодарностях,
например, такого: «... я также благодарен своему редактору, который, наверное,
чемто занимался, пока я корпел над рукописью». Но без моего редактора ,  Дэбби
Лафферти (Debbie Lafferty), эта книга вообще не увидела бы света. Когда я явился к ней с малоинтересным предложением написать заурядный учебник по программированию, она предложила вместо этого расширить главу, посвященную
скользким местам. Я отказывался. Она настаивала. Последнее слово осталось за
ней. К счастью, Дэбби была достаточно тактична, во всяком случае, извечного редакторского: «Ну, мы же вам говорили», я от нее не слышал. Ну и, кроме того, онато уж точно коечем занималась, пока я корпел над рукописью.
Я также выражаю благодарность рецензентам, которым делились своим временем и опытом, чтобы эта книга получилась лучше. Рецензировать сырую рукопись – занятие небыстрое, часто утомительное, иногда вызывающее раздражение.
Это акт профессиональной любезности, не приносящий почти никаких материальных выгод (см. «Совет 12»). Я весьма ценю глубокие, а иногда колкие комментарии своих рецензентов. Советами по техническим вопросам и нормам общественной морали, исправлениями, фрагментами кода и ехидными замечаниями со
мной поделились Стив Клэмидж (Steve Clamage), Томас Гшвинд (Thomas
Gschwind), Брайан Керниган (Brian Kernighan), Патрик МакКиллен (Patrick
McKillen), Джеффри Олдэм (Jeffrey Oldham), Дэн Сакс (Dan Saks), Мэттью Уилсон (Matthew Wilson) и Леор Золман (Leor Zolman).
Леор начал рецензировать книгу задолго до того, как появилась рукопись, поскольку посылал мне ядовитые комментарии на публикации в Web ранних вариантов некоторых из описанных в этой книге скользких мест. Сара Хьюинс (Sarah
Hewins) – мой лучший друг и самый строгий критик – заслужила оба эти титула,
рецензируя разные версии рукописи. Дэвид Р. Дьюхэрст (David R. Dewhurst) часто откладывал весь проект на неопределенное время. Грег Комей (Greg Comeau)
любезно позволил мне пользоваться своим замечательным и полностью поддерживающим стандарт C++ компилятором для проверки кода.
Как и любая нетривиальная книга по C++, эта является плодом трудов многих
людей. На протяжении ряда лет мои студенты, клиенты и коллеги обогащали мой,
не сказать, чтобы счастливый, опыт преодоления скользких мест C++, а многие
помогали находить решения проблем. Шаблон Select в «Совете 11» и политика OpNewCreator из «Совета 70» были впервые были опубликованы к книге
Andrei Alexandrescu «Modern C++ Design»*.

* Имеется русский перевод: Андрей Александреску «Современное проектирование
на C++», издательский дом «Вильямс», 2002. (Прим. перев.)

14
14
14
14
Благодарность
Благодарность
Благодарность
Благодарность
Благодарность

С проблемой возврата ссылки на константный аргумент, описанной в «Совете
44», я впервые столкнулся в книге Cline и др. «C++ FAQ» («Часто задаваемые вопросы по C++»), после чего она немедленно стала появляться в коде, написанном
моими клиентами. Там же описывается упомянутый в «Совете 73» способ, позволяющий уйти от применения перегруженных виртуальных функций.
Шаблон Cptr из «Совета 83» – это модифицированная версия шаблона
CountedPtr, описанного в книге Nicolai Josuttis «The C++ Standard Library»
(Стандартная библиотека C++).
Скотт Мейерс немало написал о нежелательности перегрузки операторов &&,
||, и , в своей книге «More Effective C++»*. В книге «Effective C++»* он подробно
обсуждает необходимость возврата результата бинарного оператора по значению,
о чем идет речь в(см. «Совете 58», а в книге «Effective STL» (Эффективное использование STL) описывает неправильное применение шаблона auto_ptr
(см. «Совет 68»). Упомянутая в «Совете 87» техника возврата константного значения из операторов постфиксного инкремента и декремента также описана
в книге «More Effective C++».
От Дэна Сакса я впервые услышал убедительные аргументы в пользу файла
с опережающими объявлениями («Совет  8»). Он же первым описал «сержантский оператор» («Совет 17») и убедил меня не проверять выход за границы диапазона значений при инкременте и декременте перечислений («Совет 87»).

* Имеется русский перевод: Скотт Мейерс «Наиболее эффективное использование
C++», издательство ДМК, 2000. (Прим. перев.)
** Имеется русский перевод: Скотт Мейерс «Эффективное использование C++», издательство ДМК, 2000. (Прим. перев.)

К покупке доступен более свежий выпуск Перейти