Скотт Мейерс - Эффективное использование STL
- Название:Эффективное использование STL
- Автор:
- Жанр:
- Издательство:Питер
- Год:2002
- Город:СПб.
- ISBN:ISBN 5-94723-382-7
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Мейерс - Эффективное использование STL краткое содержание
В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.
Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.
Эффективное использование STL - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
map m;
ключ относится к типу string
, а ассоциированное значение — к типу double
.
Примеры
Книга содержит множество примеров. Все примеры комментируются по мере их приведения, и все же кое-что следует пояснить заранее.
Из приведенного выше примера с map
видно, что я обычно опускаю директивы #include
и игнорирую тот факт, что компоненты STL принадлежат пространству имен std. Полное определение m должно было выглядеть так:
#include
#include
using std::map;
using std::string;
map m;
Но я предпочитаю оставить в примере лишь самое существенное. При объявлении формального параметра-типа шаблона вместо class
используется ключевое слово typename
. Иначе говоря, вместо конструкции вида
template
class Widget{...};
я использую конструкцию
template Т>
class Widget{...};
В данном контексте ключевые слова class
и typename
эквивалентны, но мне кажется, что слово typename
более четко выражает важную мысль: подходит любой тип, Т не обязательно является классом. Если вы предпочитаете объявлять параметры с ключевым словом class
— пожалуйста. Выбор между typename
и class
в этом контексте зависит только от стиля.
Однако в других контекстах стиль не является единственным фактором. Во избежание потенциальных неоднозначностей лексического анализа (я избавлю вас от подробностей) имена типов, зависящие от формальных параметров шаблона, должны предваряться ключевым словом typename
. Такие типы называются зависимыми типами. Небольшой пример поможет вам лучше понять, о чем идет речь. Предположим, вы пишете шаблон функции, которая получает контейнер STL и возвращает результат проверки условия «последний элемент контейнера больше первого». Одно из возможных решений выглядит так:
template
bool latGreaterThanFirst(const С& container)
{
if(container.empty()) return false:
typenameC::const_iterator begin(container.begin());
typenameC::const_iterator end(container.end());
return *--end > *begin;
}
В этом примере локальные переменные begin
и end
относятся к типу С::const_iterator
, зависящему от формального параметра С. Поскольку тип С:: const_iterator
является зависимым, перед ним должно стоять ключевое слово typename
. Некоторые компиляторы принимают код без typename
, но такой код не переносится на другие платформы.
Надеюсь, вы обратили внимание на жирный шрифт в приведенных примерах. Выделение должно привлечь ваше внимание к особенно важным фрагментам кода. Нередко таким образом подчеркиваются различия между похожими примерами, как, например, при демонстрации двух разных способов объявления параметра Т в примере Widget
. Аналогичным образом помечаются и важные блоки на рисунках. Например, на диаграмме из совета 5 таким образом помечаются два указателя, изменяемые при вставке нового элемента в список.

В книге часто встречаются параметры lhs
и rhs
. Эти сокращения означают «left-hand side» («левая сторона») и «right-hand side» («правая сторона») соответственно, они особенно удобны при объявлении операторов. Пример из совета 19:
class Widget {...}:
bool operator==(const Widget& lhs .const Widgets rhs):
При вызове этой функции в контексте
if (х==у) // Предполагается, что х и у
// относятся к классу Widget
Объекту х, находящемуся слева от оператора =, в объявлении operator -= соответствует параметр Ihs, а объекту у соответствует параметр rhs.
Что касается имени класса Widge t, то оно не имеет никакого отношения к графическим интерфейсам или инструментариям. Этим именем я привык обозначать «некий класс, который что-то делает». Иногда (как, например, на с. 20) имя Widget относится к шаблону класса, а не к классу. В таких случаях я продолжаю говорить о Widget как о классе несмотря на то, что в действительности это шаблон. Столь неформальное отношение к различиям между классами и шаблонами классов, структурами и шаблонами структур, функциями и шаблонами функций безвредно (при условии, что оно не приводит к возникновению неоднозначности в рассматриваемой теме). Если возможны какие-либо недоразумения, я провожу четкие различия между шаблонами и сгенерированными на их основе классами, структурами и функциями.
Вопросы эффективности
Сначала я хотел включить в книгу отдельную главу, посвященную вопросам эффективности, но в итоге решил, что лучше оставить привычное деление на советы. Тем не менее многие советы посвящены минимизации затрат памяти и ресурсов на стадии исполнения. Для удобства ниже приводится краткое содержание «виртуальной главы», посвященной эффективности.
Совет 4.Вызывайте empty вместо сравнения size() с нулем
Совет 5.Используйте интервальные функции вместо одноэлементных
Совет 14.Используйте reserve для предотвращения лишних операций перераспределения памяти
Совет 15.Помните о различиях в реализации string
Совет 23.Рассмотрите возможность замены ассоциативных контейнеров сортированными векторами
Совет 24.Тщательно выбирайте между map::operator[] и map::insert
Совет 25.Изучите нестандартные хэшированные контейнеры
Совет 29.Рассмотрите возможность использования istreambuf_iterator при посимвольном вводе
Совет 31.Помните о существовании разных средств сортировки
Совет 44.Используйте функции контейнеров вместо одноименных алгоритмов
Совет 46.Передавайте алгоритмам объекты функций вместо функций
Рекомендации
Рекомендации, составляющие 50 советов этой книги, основаны на мнениях и наблюдениях опытнейших программистов STL. Они в краткой форме подводят итог всему, что практически всегда следует (или наоборот, не следует) делать для успешного использования библиотеки STL. С другой стороны, это всего лишь рекомендации, и в некоторых ситуациях их нарушения вполне оправданны. Например, в заголовке совета 7 говорится о необходимости вызова delete
для указателей перед уничтожением контейнера. Но из текста совета становится ясно, что это правило действует лишь в тех случаях, когда объекты, на которые ссылаются указатели, должны уничтожаться раньше самого контейнера. Обычно это действительно так, но не всегда. Приведу другой пример — в заголовке совета 35 предлагается использовать алгоритмы STL для выполнения простых сравнений строк без учета регистра, но из текста совета следует, что в некоторых случаях лучше использовать функцию не только внешнюю по отношению к STL, но даже не входящую в стандарт С++!
Интервал:
Закладка: