Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
При использовании шаблонов шаблонов (шаблонов… и т.д.) объявления становятся очень длинными, что затрудняет их чтение, так что облегчите себе жизнь, использовав typedef
. Более того, использование typedef
облегчает внесение изменений в объявление шаблонов, избавляя от необходимости выполнять поиск и замену во многих местах большого количества исходных файлов.
Класс DBConn
— это фиктивный класс, который представляет подключение к реляционной базе данных. Интересно здесь то, как в SimpleTxnLog
определяется метод addTxn
. В начале этой функции я смотрю, существует ли уже объект набора для переданного id
.
SetStr* pSet = log_[id];
log_
— это map
(см. рецепт 6.6), так что operator[]
выполняет поиск id
и смотрит, связаны ли с ним какие-либо данные. Если да, то возвращается объект данных, и pSet
не равен NULL
. Если нет, он создается, и возвращается указатель, который будет равен NULL
. Затем я проверяю, указывает ли на что-то pSet
, и определяю, требуется ли создать еще один набор.
if (pSet == NULL) {
pSet = new SetStr(); // SetStr = std::set
log_[id] = pSet;
}
Так как pSet
— это копия объекта данных, хранящихся в map (указатель на набор), а не само значение, то после создания set
я должен поместить его обратно в связанный с ним ключ в map
. После этого все, что остается сделать, — это добавить элемент в набор и выйти.
pSet->insert(sql);
Выполнив указанные шаги, я в один контейнер ( map
) добавил указатель на адрес другого контейнера ( set
). Что я не делал — это добавление объекта set
в map
. Разница очень существенна. Так как контейнеры обладают семантикой копирования, следующий код приведет к копированию всего набора s
в map
.
set s;
// Заполнить s данными...
log_[id] = s; // Скопировать s и добавить его копию в log_
Это приведет к огромному числу дополнительных нежелательных копирований. Следовательно, общее правило при использовании контейнеров из контейнеров — это использовать указатели на контейнеры.
Глава 7
Алгоритмы
7.0. Введение
Эта глава рассказывает, как работать со стандартными алгоритмами и как использовать их для стандартных контейнеров. Эти алгоритмы первоначально являлись частью того, что часто называется Standard Template Library (STL — стандартная библиотека шаблонов) и представляет собой набор алгоритмов, итераторов и контейнеров, которые теперь вошли в стандартную библиотеку (глава 6 содержит рецепты по работе со стандартными контейнерами). Я их буду называть просто стандартными алгоритмами, итераторами и контейнерами, но не забывайте, что это то же самое, что другие авторы называют частью STL. Одним из базовых элементов стандартной библиотеки являются итераторы, так что первый рецепт описывает, что они собой представляют и как их использовать. После этого идет несколько рецептов, которые объясняют, как использовать и расширять стандартные алгоритмы. Наконец, если вы не нашли ничего подходящего в стандартной библиотеке, то рецепт 7.10 расскажет, как написать собственный алгоритм.
Представленные здесь рецепты в основном предназначены для работы со стандартными контейнерами, и тому есть две причины. Во-первых, стандартные контейнеры очень распространены, и лучше изучить стандарт, чем изобретать колесо. Во-вторых, реализация алгоритмов из стандартной библиотеки предоставляет хороший пример для подражания в смысле взаимодействия и производительности. Если вы посмотрите, как профессионалы выполнили код стандартной библиотеки, вы, скорее всего, узнаете много нового и полезного для себя.
Все стандартные алгоритмы используют итераторы. Даже если вы знакомы с концепцией итераторов, которые рассматриваются в первом рецепте, посмотрите на табл. 7.1, которая содержит перечень соглашений, используемых в остальных рецептах главы при демонстрации объявлений функций стандартных алгоритмов.
Табл. 7.1. Сокращения категорий итераторов
Сокращение | Значение |
---|---|
In | Input iterator (Итератор ввода) |
Out | Output iterator (Итератор вывода) |
Fwd | Forward iterator (Однонаправленный итератор) |
Bid | Bidirectional iterator (Двунаправленный итератор) |
Rand | Random-access iterator (Итератор произвольного доступа) |
Стандартные алгоритмы также используют функциональные объекты, или функторы . Функциональный объект — это класс, который переопределяет operator()
так, что его можно вызвать как функцию. Функтор, который возвращает bool
(и не поддерживает состояния, и, следовательно, называется чистым (pure) , называется предикатом (predicate) , и он является еще одной обычной функциональной особенностью стандартных алгоритмов. Обычно предикат принимает один или два аргумента: если он принимает один аргумент, то это унарный предикат, а если два — то бинарный предикат. Для краткости я при демонстрации объявлений функций использую сокращения, приведенные в табл. 7.2.
Табл. 7.2. Типы функторов
Имя типа | Описание |
---|---|
UnPred | Унарный предикат. Принимает один аргумент и возвращает bool |
BinPred | Бинарный предикат. Принимает два аргумента и возвращает bool |
UnFunc | Унарная функция. Принимает один аргумент и возвращает некое значение |
BinFunc | Бинарная функция. Принимает два аргумента и возвращает некое значение |
В большинстве случаев там, где требуется аргумент в виде функтора, может использоваться указатель на функцию. При использовании термина «функтор» я также подразумеваю указатель на функцию, если не указано иного.
7.1. Перебор элементов контейнера
Имеется диапазон итераторов — скорее всего, из стандартного контейнера — и стандартные алгоритмы не удовлетворяют вашим требованиям, так что вам требуется выполнить итерации самостоятельно.
Для доступа к элементам контейнера и перехода от одного элемента к другому используйте iterator
или const_iterator
. В стандартной библиотеке алгоритмы и контейнеры взаимодействуют с помощью итераторов, и одной из базовых идей стандартных алгоритмов является то, что они избавляют вас от необходимости непосредственного использования итераторов, за исключением тех случаев, когда вы пишете собственный алгоритм. И даже в этом случае вы должны понимать различные типы итераторов с тем, чтобы эффективно использовать стандартные алгоритмы и контейнеры. Пример 7.1 представляет некоторые простые способы использования итераторов.
Пример 7.1. Использование итераторов с контейнерами
Читать дальшеИнтервал:
Закладка: