Наиболее эффективное использование С++. 35 новых рекомендаций по улучшению ваших программ и проектов
Покупка
Тематика:
Программирование на C и C++
Издательство:
ДМК Пресс
Автор:
Мейерс Скотт
Год издания: 2007
Кол-во страниц: 294
Дополнительно
Вид издания:
Практическое пособие
Уровень образования:
Аспирантура
ISBN: 5-94074-033-2
Артикул: 615955.01.99
К покупке доступен более свежий выпуск
Перейти
Автор книги «Наиболее эффективное использование C++» предлагает 35 новых способов улучшения ваших программ. Основываясь на своем многолетнем опыте, С. Мейерс объясняет, как писать наиболее эффективные программы: надежные, совместимые, переносимые и пригодные для повторного использования, то есть программы, безупречные во всех отношениях. Настоящая книга описывает приемы, которые позволяют значительно повысить производительность программ, выбрав оптимальное соотношение затрат времени/памяти на различные операции. Здесь вы найдете примеры об- работки исключений и анализ их влияния на структуру и поведение классов и функций C++, а также варианты практического применения новых возможно- стей языка, таких как тип bool, ключевые слова mutable и explicit, пространства имен, шаблоны функций членов, стандартная библиотека шаблонов и многое другое.
Тематика:
ББК:
УДК:
ОКСО:
- ВО - Бакалавриат
- 09.03.01: Информатика и вычислительная техника
- 09.03.02: Информационные системы и технологии
- 09.03.03: Прикладная информатика
ГРНТИ:
Скопировать запись
Фрагмент текстового слоя документа размещен для индексирующих роботов
Наиболее эффективное использование C++ 35 новых рекомендаций по улучшению ваших программ и проектов Скотт Мейерс
More effective C++ Scott Meyers 35 New Ways to Improve Your Programs and Designs An imprint of Addison Wesley Longman, Inc.
Наиболее эффективное использование C++ Скотт Мейерс Москва 35 новых рекомендаций по улучшению ваших программ и проектов Серия «Для программистов»
УДК 004.4 ББК 32.973.26-018.2 М97 МейерсС. М97 Наиболее эффективное использование С++. 35 новых рекомендаций по улучшению ваших программ и проектов. – М.: ДМК Пресс. – 294 с.: ил. ISBN 5-94074-033-2 Автор книги «Наиболее эффективное использование C++» предлагает 35 новых способов улучшения ваших программ. Основываясь на своем многолетнем опыте, С. Мейерс объясняет, как писать наиболее эффективные программы: надежные, совместимые, переносимые и пригодные для повторного использования, то есть программы, безупречные во всех отношениях. Настоящая книга описывает приемы, которые позволяют значительно по высить производительность программ, выбрав оптимальное соотношение затрат времени/памяти на различные операции. Здесь вы найдете примеры обработки исключений и анализ их влияния на структуру и поведение классов и функций C++, а также варианты практического применения новых возможностей языка, таких как тип bool, ключевые слова mutable и explicit, пространства имен, шаблоны функций членов, стандартная библиотека шаблонов и многое другое. УДК 004.438 ББК 32.973.26-018.2 Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Материал, изложенный в данной книге, многократно проверен. Но поскольку вероят ность технических ошибок все равно существует, издательство не может гарантировать абсолютную точность и правильность приводимых сведений. В связи с этим издательство не несет ответственности за возможные ошибки, связанные с использованием книги. © Pearson Education, Inc ISBN 5-94074-033-2 © Перевод на русский язык, оформление, издание, ДМК Пресс, 2012
Это блестящая книга, проясняющая многие аспекты языка C++, начиная с редко используемых его свойств и заканчивая разделами, которые программисты считают простыми и недвусмысленными. Только глубоко понимая, каким образом компилятор C++ обрабатывает исходные тексты программ, можно надеяться на создание надежного программного обеспечения. Эта книга является бесценным источником такого понимания. Прочитав книгу, я как будто вместе с большим специалистом по C++ отредактировал огромное количество исходных текстов и получил от него массу очень ценных наставлений. Фред Вайлд (Fred Wild), вицепрезидент по технологиям, Advantage Software Technologies Эта книга описывает множество важных приемов, позволяющих писать эффективные программы на C++. В ней объясняется, как придумывать и реализовывать идеи и как не попасться впросак, используя ту или иную архитектуру программы. В книге также подробнейше рассматриваются новые свойства, недавно добавленные к C++. Любой программист, желающий использовать эти свойства, обязательно захочет иметь под рукой такую книгу. Кристофер Дж. Ван Вык (Christopher J. Van Wyk), профессор, подразделение математики и компьютерных наук, Университет Дрю В пособии представлены возможности промышленного применения языка С++ в лучшем смысле этого слова. Превосходная книга для тех, кто читал предыдущую – «Эффективное использование C++». Эрик Наглер (Eric Nagler), преподаватель и автор книг, Калифорнийский университет, отделение в Санта Круз «Наиболее эффективное использование C++» – ценное продолжение первой книги Скотта «Эффективное использование C++». Я считаю, что каждый профессиональный разработчик на C++ должен прочесть и постоянно держать в памяти советы из этих двух книг. Все они, по моему мнению, касаются очень важных, но плохо понимаемых аспектов языка. Я настоятельно рекомендую эту книгу, также как и предыдущую, разработчикам, бетатестерам и руководителям проектов; глубокие знания автора и превосходный стиль изложения делают ее полезной для всех. Стив Беркетт (Steve Burkett), консультант по программному обеспечению
Содержание Благодарности ............................................................................................ 9 Источники идей ........................................................................................... 9 Об этой книге ............................................................................................ 11 Люди, которые мне помогали .................................................................... 13 Введение .......................................................................................................... 14 Глава 1. Основы ............................................................................................. 23 Правило 1. Различайте указатели и ссылки ............................................... 23 Правило 2. Предпочитайте приведение типов в стиле С++ ........................ 25 Правило 3. Никогда не используйте полиморфизм в массивах .................. 30 Правило 4. Избегайте неоправданного использования конструкторов по умолчанию ............................................................................................ 33 Глава 2. Операторы ...................................................................................... 38 Правило 5. Опасайтесь определяемых пользователем функций преобразования типа ................................................................................ 38 Правило 6. Различайте префиксную и постфиксную формы операторов инкремента и декремента ......................................................................... 45 Правило 7. Никогда не перегружайте операторы &&, || и ,......................... 48 Правило 8. Различайте значение операторов new и delete ......................... 51 Глава 3. Исключения .................................................................................... 57 Правило 9. Чтобы избежать утечки ресурсов, используйте деструкторы .............................................................................................. 58 Правило 10. Не допускайте утечки ресурсов в конструкторах .................... 63 Правило 11. Не распространяйте обработку исключений за пределы деструктора .............................................................................................. 71 Правило 12. Отличайте генерацию исключения от передачи параметра или вызова виртуальной функции ............................................ 73 Правило 13. Перехватывайте исключения, передаваемые по ссылке ........ 80 Правило 14. Разумно используйте спецификации исключений .................. 84 Правило 15. Оценивайте затраты на обработку исключений ...................... 90
Содержание Глава 4. Эффективность ............................................................................ 94 Правило 16. Не забывайте о правиле «80–20» ........................................... 95 Правило 17. Используйте отложенные вычисления ................................... 97 Правило 18. Снижайте затраты на ожидаемые вычисления ..................... 106 Правило 19. Изучите причины возникновения временных объектов ........ 110 Правило 20. Облегчайте оптимизацию возвращаемого значения ............ 113 Правило 21. Используйте перегрузку, чтобы избежать неявного преобразования типов ............................................................................ 116 Правило 22. По возможности применяйте оператор присваивания вместо отдельного оператора ................................................................. 118 Правило 23. Используйте разные библиотеки ......................................... 121 Правило 24. Учитывайте затраты, связанные с виртуальными функциями, множественным наследованием, виртуальными базовыми классами и RTTI ...................................................................... 124 Глава 5. Приемы ...........................................................................................134 Правило 25. Делайте виртуальными конструкторы и функции, не являющиеся членами класса............................................................... 134 Правило 26. Ограничивайте число объектов в классе .............................. 140 Правило 27. В зависимости от ситуации требуйте или запрещайте размещать объекты в куче ....................................................................... 154 Правило 28. Используйте интеллектуальные указатели ........................... 167 Правило 29. Используйте подсчет ссылок ............................................... 190 Правило 30. Применяйте proxy-классы .................................................... 218 Правило 31. Создавайте функции, виртуальные по отношению более чем к одному объекту .................................................................... 231 Глава 6. Разное ..............................................................................................254 Правило 32. Программируйте, заглядывая в будущее ............................. 254 Правило 33. Делайте нетерминальные классы абстрактными ................. 259 Правило 34. Умейте использовать в одной программе С и С++................ 270 Правило 35. Ознакомьтесь со стандартом языка ..................................... 276 Приложение 1. Список рекомендуемой литературы .....................................................................................................284 Приложение 2. Реализация шаблона auto_ptr .................................289 Алфавитный указатель ..............................................................................293 7
Клэнси, моему любимому внутреннему противнику, посвящается
Благодарности В создании этой книги принимало участие множество людей. Одни предложили важные технические идеи, другие помогли подготовить ее к печати, а третьи просто скрашивали мою жизнь, пока я работал над ней. Часто, когда количество людей, принимавших участие в работе над книгой, достаточно велико, появляется соблазн отказаться от перечисления участников проекта, ограничившись стандартной фразой «Список людей, работавших над книгой, слишком длинен, чтобы быть приведенным здесь». Я, однако, предпочитаю подход Джона Л. Хеннеси (John L. Hennessey) и Дэвида А. Петерсона (David A. Patterson) – см. «Компьютерные архитектуры: численный подход», изд. Морган Кауфман (Morgan Kaufman), 1ое издание, 1990. Один из аргументов за включение полного списка благодарностей, приведенного ниже, – статистические данные для закона «80–20», на который я ссылаюсь в правиле 16. Источники идей За исключением прямого цитирования, весь текст этой книги принадлежит мне. Тем не менее, многие описанные в ней идеи были придуманы другими. Я всячески пытался отслеживать авторство нововведений, но мне все же пришлось включить информацию из источников, названия которых я уже не могу вспомнить, в основном это сообщения из конференций Usenet comp.lang.c++ и comp.std .c++. Многие идеи в сообществе C++ зарождаются почти одновременно и совершенно независимо в головах многих людей. Ниже я указываю только, где услышал ту или иную мысль, что не всегда совпадает с тем, где она была озвучена впервые. Брайан Керниган (Brian Kernighan) предложил использовать макроопределения для приближения к синтаксису новых операторов приведения типа, описанных в правиле 2. Предупреждение по поводу удаления массива объектов производного класса с помощью указателя на базовый класс, изложенное в правиле 3, основано на материалах лекции Дэна Сакса (Dan Saks), прочитанной им на нескольких конференциях и торговых выставках. Техника использования proxyклассов из правила 5, позволяющая избежать нежелательного вызова конструкторов с одним аргументом, основана на материалах колонки Эндрю Кенига (Andrew Koenig) в журнале C++ Report за январь 1994 года. Джеймс Канце (James Kanze) прислал сообщение в comp.lang.c++ относительно реализации постфиксных декрементных и инкрементных операторов через соответствующие префиксные операторы. Этот прием рассматривается в правиле 6. Дэвид Кок (David Cok), написав мне по одному вопросу, затронутому в «Эффективном использовании C++», привлек мое внимание к различию между operator new и оператором new, положенному в основу правила 8. Даже прочитав письмо, я не в полной мере осознал существующую разницу, но если бы не этот первый толчок, то, скорее всего, не понимал бы ее до сих пор.
10 Метод записи деструкторов, позволяющий избежать утечки ресурсов (см. правило 9), взят из раздела 15.3 книги Маргарет А. Эллис (Margaret A. Ellis) и Бьерна Страуструпа (Bjarne Stroustrup) The Annotated C++ Reference Manual. Там этот метод имеет название «Выделение ресурса – инициализация». Том Каргилл (Tom Cargill) предложил перенести акцент с выделения ресурсов на их освобождение. Часть рассуждений в разделе, посвященном правилу 11, была навеяна содержимым главы 4 книги Taligent’s Guide to Designing Programs, изд. AddisonWesley, 1994. Описание предварительного выделения памяти для класса DynArray в правиле 18 основано на статье Тома Каргилла «Динамический вектор сложнее, чем кажется», опубликованной в журнале C++ Report за июнь 1992 года. Информацию о более сложной архитектуре для класса динамического массива можно найти в заметке того же автора (номер C++ Report за январь 1994 года). Правило 21 появилось благодаря докладу Брайана Кернигана «AWK для транслятора C++» на конференции USENIX по C++ в 1991 году. Его идея использовать перегруженные операторы (общим числом 67!) для выполнения арифметических операций с операндами разных типов хотя и не была связана с проблемой, обсуждаемой в правиле 21, но заставила меня рассмотреть множественную перегрузку операторов в качестве решения задачи по созданию временных объектов. Мой вариант шаблона класса для подсчета объектов, рассмотренный в правиле 26, основан на сообщении Джамшида Афшара (Jamshid Afshar) в конференцию comp.lang.c++. Идея смешанного класса, позволяющего отслеживать указатели, созданные с помощью operator new (см. правило 27), базируется на предложении Дона Бокса (Don Box). Стив Клемидж (Steve Clamage) придал этой идее практическое значение, объяснив, как можно использовать dynamic_cast для нахождения начала области памяти, занимаемой объектом. Описание smartуказателей в правиле 28 основано: частично на заметке Стивена Буроффа (Steven Buroff) и Роба Мюррея (Rob Murray) C++ Oracle в журнале C++ Report за октябрь 1993 года, на классической работе Даниэла Р. Эдельсона (Daniel R. Edelson) «Интеллектуальные (smart) указатели: интеллектуальные, но не указатели» в материалах конференции USENIX по C++ от 1992 года, на содержимом раздела 15.9.1 книги Бьерна Страуструпа «Архитектура и развитие C++», на докладе Грегори Колвина (Gregory Colvin) «Управление памятью в C++» на учебном семинаре «Решения для С/С++ ‘95» и на заметке Кея Хорстманна (Cay Horstmann) в мартовском и апрельском номерах C++ Report за 1993 год. Но коечто сделал и я сам. Использованный в правиле 29 метод хранения в базовом классе счетчиков ссылок и smartуказателей для работы с этими счетчиками основан на идее Роба Мюррея (см. разделы 6.3.2 и 7.4.2 его книги «Стратегия и тактика в C++»). Прием, позволяющий добавлять счетчики ссылок к существующим классам, аналогичен тому, что был предложен Кеем Хорстманном в заметке, опубликованной в мартовском и апрельском номерах журнала C++ Report за 1993 год. Источником для правила 30, касающегося контекстов lvalue, послужили комментарии к заметке Дэна Сакса в журнале C User’s Journal (теперь C/C++ Наиболее эффективное использование C++
К покупке доступен более свежий выпуск
Перейти