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

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

• создать ассоциативный массив;

• использовать ассоциативный массив.

Мы создаем объект класса

multimap
путем обхода всех сообщений и их вставки с помощью функции
insert
:

for (Mess_iter p = mfile.begin; p!=mfile.end; ++p) {

const Message& m = *p;

string s;

if (find_from_addr(&m,s))

sender.insert(make_pair(s,&m));

}

В

ассоциативный массив включаются пары (ключ, значение), созданные с помощью функции
make_pair
. Для того чтобы найти имя отправителя, используем “кустарную” функцию
find_from_addr
.

Почему мы используем ссылку

m
и передаем ее адрес? Почему не использовать итератор
p
явно и не вызвать функцию так:
find_from_addr(p,s)
? Потому что, даже если мы знаем, что итератор
Mess_iter
ссылается на объект класса
Message
, нет никакой гарантии, что он реализован как указатель.

Почему мы сначала записали объекты класса

Message
в вектор, а затем создали объект класса
multimap
? Почему сразу не включить объекты класса
Message
в ассоциативный массив класса
map
? Причина носит простой и фундаментальный характер.

• Сначала мы создаем универсальную структуру, которую можно использовать для многих вещей.

• Затем используем ее в конкретном приложении.

Таким образом, мы создаем коллекцию в той или иной степени повторно используемых компонентов. Если бы мы сразу создали ассоциативный массив в объекте класса
Mail_file
, то вынуждены были бы переопределять его каждый раз, когда хотим использовать его для решения другой задачи. В частности, наш объект класса
multimap
(многозначительно названный
sender
) упорядочен по полю
Address
. Большинство других приложений могут использовать другой критерий сортировки: по полям Return, Recipients, Copy-to fields, Subject fields, временным меткам и т.д.

Создание приложений по этапам (или слоям (layers), как их иногда называют) может значительно упростить проектирование, реализацию, документацию и эксплуатацию программ. Дело в том, что каждая часть приложения решает отдельную задачу и делает это вполне очевидным образом. С другой стороны, для того чтобы сделать все сразу, нужен большой ум. Очевидно, что извлечение информации и заголовков сообщений электронной почты — это детский пример приложения. Значение разделения задач, выделения модулей и поступательного наращивания приложения по мере увеличения масштаба приложения проявляется все более ярко.

Для того чтобы извлечь информацию, мы просто ищем все упоминания ключа "John Doe", используя функцию

equal_range
(раздел Б.4.10). Затем перемещаемся по всем элементам в последовательности
[first,second]
, возвращаемой функцией
equal_range
, извлекая темы сообщений с помощью функции
find_subject
.

typedef multimap<string, const Message*>::const_iterator MCI;

pair<MCI,MCI> pp = sender.equal_range("John Doe");

for (MCI p = pp.first; p!=pp.second; ++p)

cout << find_subject(p–>second) << '\n';

Перемещаясь

по элементам объекта класса map, мы получаем последовательность пар (ключ,значение), в которых, как в любом другом объекте класса
pair
, первый элемент (в данном случае ключ класса
stringkey
) называется
first
, а второй (в данном случае объект класса
Message
) —
second
(см. раздел 21.6).

23.4.1. Детали реализации

Очевидно, что мы должны реализовать используемые нами функции. Соблазнительно, конечно, сэкономить бумагу и спасти дерево, предоставив читателям самостоятельно решить эту задачу, но мы решили, что пример должен быть полным.

Конструктор класса

Mail_file
открывает файл и создает векторы
lines
и
m
.

Mail_file::Mail_file(const string& n)

// открывает файл с именем "n"

// считывает строки из файла "n" в вектор lines

// находит сообщения в векторе lines и помещает их в вектор m,

// для простоты предполагая, что каждое сообщение заканчивается

// строкой "––––" line

{

ifstream in(n.c_str); // открываем файл

if (!in) {

cerr << " нет " << n << '\n';

exit(1); // прекращаем выполнение программы

}

string s;

while (getline(in,s)) lines.push_back(s); // создаем вектор

// строк

Line_iter first = lines.begin; // создаем вектор сообщений

for (Line_iter p = lines.begin; p!=lines.end; ++p) {

if (*p == "––––") { // конец сообщения

m.push_back(Message(first,p));

first = p+1; // строка –––– не является частью

// сообщения

}

}

}

Обработка ошибок носит слишком элементарный характер. Если бы писали эту программу для своих друзей, то постарались бы сделать ее лучше.

ПОПРОБУЙТЕ

Что значит “более хорошая обработка ошибок”? Измените конструктор класса

Mail_file
так, чтобы он реагировал на ошибки форматирования, связанные с использованием строки “––––”.

Поделиться:
Популярные книги

Измена. За что ты так со мной

Дали Мила
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. За что ты так со мной

Неудержимый. Книга II

Боярский Андрей
2. Неудержимый
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга II

Большие дела

Ромов Дмитрий
7. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Большие дела

Эксклюзив

Юнина Наталья
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Эксклюзив

И только смерть разлучит нас

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
И только смерть разлучит нас

Черкес. Дебют двойного агента в Стамбуле

Greko
1. Черкес
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черкес. Дебют двойного агента в Стамбуле

Один на миллион. Трилогия

Земляной Андрей Борисович
Один на миллион
Фантастика:
боевая фантастика
8.95
рейтинг книги
Один на миллион. Трилогия

Ваше Сиятельство 8

Моури Эрли
8. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 8

Третье правило дворянина

Герда Александр
3. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Третье правило дворянина

Ваантан

Кораблев Родион
10. Другая сторона
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Ваантан

Невеста

Вудворт Франциска
Любовные романы:
любовно-фантастические романы
эро литература
8.54
рейтинг книги
Невеста

Романов. Том 1 и Том 2

Кощеев Владимир
1. Романов
Фантастика:
фэнтези
попаданцы
альтернативная история
5.25
рейтинг книги
Романов. Том 1 и Том 2

Кодекс Крови. Книга ХII

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

Бальмануг. (Не) Любовница 2

Лашина Полина
4. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Бальмануг. (Не) Любовница 2