Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ - Скотт Майерс
Шрифт:
Интервал:
Закладка:
Параграф 19: Изучите причины возникновения временных объектов
Параграф 20: Облегчайте оптимизацию возвращаемого значения
Параграф 21: Используйте перегрузку, чтобы избежать неявного преобразования типов
Параграф 22: По возможности применяйте оператор присваивания вместо отдельного оператора
Параграф 23: Используйте разные библиотеки
Параграф 24: Учитывайте затраты, связанные с виртуальными функциями, множественным наследованием, виртуальными базовыми классами и RTTI
Приемы
Параграф 25: Делайте виртуальными конструкторы и функции, не являющиеся членами класса
Параграф 26: Ограничивайте числа объектов в классе
Параграф 27: В зависимости от ситуации требуйте или запрещайте размещать объекты в куче
Параграф 28: Используйте интеллектуальные указатели
Параграф 29: Используйте подсчет ссылок
Параграф 30: Применяйте прокси-классы
Параграф 31: Создавайте функции, виртуальные по отношению более чем к одному объекту
Разное
Параграф 32: Программируйте, заглядывая в будущее
Параграф 33: Делайте нетерминальные классы абстрактными
Параграф 34: Умейте использовать C++ и C в одной программе
Параграф 35: Ознакомьтесь со стандартом языка
Эффективное использование STLГлава 1: Контейнеры
Параграф 1: Проявляйте здравый смысл при выборе контейнера
Параграф 2: Остерегайтесь иллюзий относительно контейнерно-независимого кода
Параграф 3: Делайте копирование объектов в контейнерах дешевым и корректным
Параграф 4: Вызывайте функцию empty вместо сравнения size() с нулем
Параграф 5: Предпочитайте функции, работающие с диапазонами, их одноэлементным аналогам
Параграф 6: Обращайте внимание на неприятные особенности синтаксического анализа в C++
Параграф 7: При использовании контейнеров, хранящих указатели, выделенные new, не забывайте вызвать delete перед уничтожением контейнера
Параграф 8: Никогда не помещайте объекты типа auto_ptr в контейнеры
Параграф 9: Тщательно выбирайте способ очистки
Параграф 10: Помните о соглашениях и ограничениях распределителей памяти
Параграф 11: О правильном применении специализированных распределителей памяти
Параграф 12: О реалистических ожиданиях относительно потоковой безопасности STL-контейнеров
Глава 2: vector и string
Параграф 13: Предпочитайте vector и string динамически выделенным массивам
Параграф 14: Используйте reserve для избежания ненужных операций перераспределения памяти
Параграф 15: Учитывайте различия в реализациях string
Параграф 16: Как передавать vector и string унаследованным программным интерфейсам
Параграф 17: Используйте «swap-трюк» для сокращения избыточной емкости
Параграф 18: Избегайте применять vector<bool>
Глава 3: Ассоциативные контейнеры
Параграф 19: Разберитесь, чем равенство отличается от эквивалентности
Параграф 20: Специфицируйте способ сравнения для ассоциативных контейнеров, содержащих указатели
Параграф 21: Позаботьтесь о том, чтобы функции сравнения возвращали false для равных значений
Параграф 22: Избегайте модификации ключей «по месту» в контейнерах set и multiset
Параграф 23: Рассмотрите замену ассоциативных контейнеров отсортированными векторами
Параграф 24: Тщательно выбирайте между map::operator[] и map::insert, когда важна эффективность.
Параграф 25: Ознакомьтесь с нестандартными кэшированными контейнерами
Глава 4: Итераторы
Параграф 26: Старайтесь использовать iterator вместо const_iterator, reverse_iterator и const_reverse_iterator
Параграф 27: Используйте distance и advance для преобразования const_iterator в iterator
Параграф 28: Научитесь использовать базовый iterator, соответствующий reverse_iterator
Параграф 29: Подумайте о применении istreambuf_iterator для посимвольного ввода
Глава 5: Алгоритмы
Параграф 30: Обеспечивайте достаточно большие целевые диапазоны при копировании
Параграф 31: Изучите различные варианты сортировки
Параграф 32: После вызова алгоритма remove или ему подобного не забывайте вызвать алгоритм erase, если действительно хотите что-то удалить
Параграф 33: Будьте осторожны при использовании алгоритма remove и ему подобных для контейнеров, содержащих указатели
Параграф 34: Не забывайте, что некоторые алгоритмы ожидают отсортированных диапазонов
Параграф 35: Реализуйте простое независимое от регистра сравнение строк с помощью алгоритмов mismatch или lexicographical_compare
Параграф 36: Разберитесь, как правильно реализовать алгоритм copy_if
Параграф 37: Используйте accumulate или for_each для суммирования диапазонов
Глава 6: Функторы, функторные классы, функции и т. п.
Параграф 38: Проектируйте классы-функторы для передачи по значению
Параграф 39: Делайте предикаты свободными функциями
Параграф 40: Делайте классы-функторы адаптируемыми
Параграф 41: Зачем нужны ptr_fun, mem_fun и mem_fun_ref
Параграф 42: Убедитесь, что less<T> означает operator<
Глава 7: Программирование с использованием STL
Параграф 43: Предпочитайте вызовы алгоритмов вручную написанным циклам
Параграф 44: Предпочитайте функции-члены алгоритмам с теми же именами
Параграф 45: О различиях между count, find, binary_search, lower_bound, upper_bound и equal_range.
Параграф 46: Рассмотрите применение функциональных объектов вместо функций в качестве параметров алгоритмов
Параграф 47: Избегайте создания кода «только для записи»
Параграф 48: Всегда включайте необходимые заголовочные файлы
Параграф 49: Научитесь понимать диагностические сообщения компилятора, касающиеся STL
Параграф 50: Посещайте Web-сайты, посвященные STL
Приложение В
Соответствие правил во втором и третьем изданиях
Третье издание «Эффективного использования C++» во многом отличается от второго, так как содержит много новой информации. Однако большая часть материала из второго издания осталась и в третьем, хотя часто и в измененной форме или последовательности. В приведенной ниже таблице показано, в каких правилах третьего издания можно найти информацию из второго издания, и наоборот.
В таблице приведено соответствие информации, но не текст. Например, идеи из правила 39 второго издания («Избегайте приведения типов вниз по иерархии наследования») теперь перенесены в правило 27 («Не злоупотребляйте приведением типов»), несмотря на то что текст и примеры в третьем издании совершенно новые. Вот более содержательный пример: во втором издании есть правило 18 («Стремитесь к таким интерфейсам классов, которые будут полными и минимальными»). Одним из основных выводов этого правила было то, что функции, которым не нужен специальный доступ к закрытым частям класса, не должны быть его членами. В третьем издании тот же вывод обосновывается другими (более серьезными) причинами, поэтому правилу 18 соответствует в третьем издании правило 23 («Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса»), хотя единственное, что объединяет эти два правила, – общность выводов.
Второе издание в третьемТретье издание во второмПримечания
1
Имеется русский перевод: Саттер Герб. Решение сложных задач на C++. Издательский дом «Вильямс», 2002 (Прим. науч. ред.).
2
Имеется русский перевод: Паттерны проектирования. СПб.: Питер (Прим. науч. ред.).
3
Более подробную информацию о функции unexpected вы можете найти, воспользовавшись своим любимым поисковым сервисом или в полном руководстве по языку C++ (возможно, стоит поискать информацию о функции set_unexpected, которая специфицирует unexpected).
4
В начале 2005 года, когда писалась настоящая книга, этот документ еще не был завершен, и его URL может измениться. Поэтому я рекомендую узнавать о его текущем адресе на странице http://aristeia.com/EC3E/TR1_info.html. Этот URL не изменится.