Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

 void apply {

for (MapStrSetStr::iterator p = log_.begin;

p != log_.end; ++p) {

conn_->beginTxn;

// Помните, что итератор отображения ссылается на объект

// типа pair<Key,Val>. Указатель на набор хранится в p->second.

for (SetStr::iterator pSql = p->second->begin;

pSql != p->second->end; ++pSql) {

string s = *pSql;

conn_->execSql(s);

cout << "Executing SQL: " << s << endl;

}

conn_->endTxn;

delete p->second;

}

log_.clear;

 }

 void purge {

for (MapStrSetStr::iterator p = log_.begin;

p != log_.end; ++p)

delete p->second;

log_.clear;

 }

 //...

private:

 MapStrSetStr log_;

 DBConn* conn_;

}
;

Обсуждение

Пример 6.12

предлагает ситуацию, где может потребоваться хранение одного контейнера в другом. Представьте, что требуется сохранить набор выражений SQL в виде пакета, выполнить их в будущем все сразу для реляционной базы данных. Именно это делает
SimpleTxnLog
. Чтобы сделать его еще полезнее, можно добавить в него другие методы, а для обеспечения безопасности — добавить обработку исключений, но целью этого примера является показать, как хранить один тип контейнеров в другом.

Для начала я создаю несколько

typedef
, облегчающих чтение кода.

typedef std::set<std::string> SetStr;

typedef std::map<std::string, SetStr*> MapStrSetStr;

При использовании шаблонов шаблонов (шаблонов… и т.д.) объявления становятся очень длинными, что затрудняет их чтение, так что облегчите себе жизнь, использовав

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<std::string>

 log_[id] = pSet;

}

Так как

pSet
— это копия объекта данных, хранящихся в map (указатель на набор), а не само значение, то после создания
set
я должен поместить его обратно в связанный с ним ключ в
map
. После этого все, что остается сделать, — это добавить элемент в набор и выйти.

pSet->insert(sql);

Выполнив указанные шаги, я в один контейнер (

map
) добавил указатель на адрес другого контейнера (
set
). Что я не делал — это добавление объекта
set
в
map
. Разница очень существенна. Так как контейнеры обладают семантикой копирования, следующий код приведет к копированию всего набора
s
в
map
.

set<string> 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 (Итератор произвольного доступа)
Поделиться:
Популярные книги

Камень. Книга восьмая

Минин Станислав
8. Камень
Фантастика:
фэнтези
боевая фантастика
7.00
рейтинг книги
Камень. Книга восьмая

Новый Рал 3

Северный Лис
3. Рал!
Фантастика:
попаданцы
5.88
рейтинг книги
Новый Рал 3

Бастард Императора. Том 4

Орлов Андрей Юрьевич
4. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 4

Право на месть

Ледова Анна
3. Академия Ровельхейм
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Право на месть

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Законы Рода. Том 11

Андрей Мельник
11. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 11

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Болотник

Панченко Андрей Алексеевич
1. Болотник
Фантастика:
попаданцы
альтернативная история
6.50
рейтинг книги
Болотник

Энфис 4

Кронос Александр
4. Эрра
Фантастика:
городское фэнтези
рпг
аниме
5.00
рейтинг книги
Энфис 4

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22