Читаем Программирование полностью

  Рассмотрим подробнее использование ассоциативных массивов. Мы использовали класс multimap (разделы 20.10 и Б.4), поскольку хотели собрать в одном месте много сообщений, поступивших из одного адреса. Стандартный класс multimap делает именно это (облегчая доступ к элементам с помощью одного и того же ключа). Очевидно (и типично), что наша задача распадается на две подзадачи:

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

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

Мы создаем объект класса 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::const_iterator MCI;

pair 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).

<p id="AutBody_Root446"><strong>23.4.1. Детали реализации</strong></p>

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

Конструктор класса 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';

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных