Простые типы 5 страница

9.9.16. Ревизия ранее созданных приложений
В этой главе вы, возможно, сами того не подозревая, создали приложение, которое обращается к системному реестру. Ниже приведен фрагмент текста функции CMultiStrin-gApp:: InitInstance() в том виде, в котором он сгенерирован AppWizard. Точно такой же вид имеет и заготовка метода CFileDemoApp:: Initlnstance().
// Измените ключ регистрации, под которым сохраняются ваши установки.
// После редактирования в этой строке должно быть нечто,
// связанное с наименованием вашей компании или организации. SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Загрузка стандартных опций INI-файлов (включая MRU).
Аббревиатура MRU означает Most Recently Used (последние, которыми пользовались, — свежие) и имеет отношение к файлам, список которых приводится в меню File после того, как вы откроете с его помощью хотя бы один файл (причем не имеет значения, когда это было сделано: в текущем или предыдущих сеансах работы приложения).

9.9.17. Полезные классы

Библиотека MFC включает не только классы для программирования графического интерфейса Windows. Она также предоставляет в распоряжение программиста множество классов, которые могут быть использованы для обработки таких специфических структур данных, как списки, массивы, переменные времени и даты, коллекции. Освоив работу с ними, вы сможете значительно повысить качество своих программ и упростить программирование сложных процедур обработки данных.
Например, классы MFC, которые оперируют массивами, допускают динамическое изменение размерности массива. В результате вам не придется создавать массив с запасом по размерности, который будет занимать огромный объем памяти. А экономное расходование такого ресурса, как память, - это большое преимущество профессионально разработанной программы. Похожими достоинствами обладают и другие классы MFC, оперирующие коллекциями.

9.9.18. Классы массивов
Классы массивов из состава библиотеки MFC позволяют создать объект, представляющий собой одномерный массив из экземпляров любого класса. Эти объекты массивов функционируют практически так же, как и всем знакомые массивы простых переменных, но MFC обеспечивает расширение или сжатие массива по ходу выполнения программы. А это, в свою очередь, означает, что впредь вам не придется заранее беспокоиться об объявлении размерности массива в расчете на самый невероятный случай. В результате навсегда уйдут в прошлое времена, когда массивы нерационально отнимали память в расчете на сочетание условий выполнения программы, которое бывает раз в сто лет. Ваше приложение будет отбирать у операционной системы столько памяти, сколько ему действительно сейчас необходимо.
В состав классов MFC, поддерживающих работу с массивами, входят CByteArray, CDWordArray, CObArray, CPtrArray, CUIntArray, CWordArray и CStringArray. Как понятно из названий классов, каждый из них предназначен для хранения данных определенного типа. Например, CUIntArray- это класс массива, хранящего целые без знака (такого типа класс будет использован в примере, который рассматривается в этом разделе). С другой стороны, класс CPtrArray используется для хранения указателей на тип void, a CObArray- массив объектов. Все классы массивов практически идентичны за исключением того, что они содержат элементы разных типов. Таким образом, освоив работу с одним классом, можете считать, что вы постигли таинства всех. В табл. E.1 представлены методы классов массивов и приведено их описание.
Таблица 4.1. Методы классов массивов

Шаблоны массивов
Поскольку все упомянутые выше классы массивов различаются только классом (типом) элементов, которые содержатся в массиве, возникает совершенно естественное желание использовать шаблоны языка С++. И действительно, эти классы фактически предвосхитили появление в Visual C++ шаблонов. В библиотеке Standard Template Library, o которой шла речь в главе 26, существует шаблон вектора, который может хранить элементы любого простого типа. Среди разработчиков распространено мнение, что использование классов массивов MFC значительно проще, чем шаблонов. Позднее в этом приложении мы остановимся на шаблонах коллекций, которые включены в состав MFC.

9.9.19. Описание приложения Array
Для того чтобы проиллюстрировать возможности работы одного из классов с массивами, мы включили в этот раздел приложение Аггау. После краткого обзора его работы вы в следующих разделах создадите его самостоятельно (с нашей, конечно, помощью). После запуска программы вы увидите на экране нечто, похожее на то, что показано на рис. 4.1. В окне выведено содержимое массива. Поскольку начальный размер объекта-массива (экземпляра класса CUIntArray) равен 10 (индексы элементов от 0 до 9), на экране вы увидите соответственно 10 строк. Приложение позволяет добавлять элементы в массив, изменять их значения, удалять элементы и все время наблюдать за результатом.

Рис. 4.1. Приложение Array позволяет экспериментировать с классами MFC, обрабатывающими массивы
Элемент в массив можно включить несколькими способами. Чтобы убедиться в этом, щелкните в окне приложения. Появится диалоговое окно, показанное на рис. 4.2. Введите значение индекса в поле Index, а желаемое значение элемента (целое число) - в поле Value. После этого нужно выбрать операцию, которую вы собираетесь выполнить, - вставить элемент, записать значение в существующий элемент или добавить элемент. При выборе переключателя Set значение, которое установлено в поле Value, будет записано в элемент, индекс которого задан полем Index. Выбор переключателя lnsert приведет в результате к вставке нового элемента в то место массива, которое задано индексом. При этом все последующие элементы сместятся по направлению к концу массива. И наконец переключатель Add "запустит" операцию добавления элемента - новый элемент будет помещен в "хвост" массива. В этом случае программа ко всем вашим стараниям, сопряженным с вводом значения индекса, отнесется совершенно наплевательски.

Рис. 4.2. Диалоговое окно Add to Array позволяет добавить элементы в массив

Рис. 4.4. Теперь на экране появился новый элемент в массиве, причем общее число элементов увеличилось до 11

Предположим, например, что вы введете значение 3 в поле Index, а значение 15 - в поле Value и оставите включенным переключатель Set. Щелкните на OK, и результат не заставит себя ждать - он на рис. 4.3. Случилось чудо! Программа установила число 15 в элемент 3 массива, заменив предыдущее значение. А теперь - новый смелый эксперимент. Введите значение 2 в поле Index, а значение 25 (ставки растут!) - в поле Value, выберите переключатель lnsert и щелкните на ОК. Вы даже не успеете затаить дыхание, как появится результат - в точности как на рис. 4.4. Программа все-таки нашла, куда вставить такое большое число, а остальным пришлось потесниться.

Рис. 4.3. Число 15 записано в элемент массива с индексом 3
Еще один смелый эксперимент - на сей раз проверим, так ли уж сообразителен класс MFC и так ли уж действительно динамичен создаваемый массив. Задайте значение индекса, выходящее за пределы текущего размера массива. Например, в том интересном положении, от которого программа еще не оправилась на рис. E.4, введите значение индекса 20, а значение элемента пусть будет 45. Выберите переключатель Set и щелкните на ОК. Результат - на рис. 4.5. Оказалось, что класс все-таки разобрался в ситуации. Хотя элемента с индексом 20 и не существовало, класс сам его создал и установил в нем заданное значение. Теперь можно особенно не беспокоиться о диапазоне значений индексов. Попробовали бы вы позволить себе подобную вольность с прежними С-массивами!

Рис. 4.5. В класс массива добавлены элементы, необходимые для формирования элемента с индексом 20

Совершенно естественно, что, кроме добавления элементов, приложение должно обеспечивать возможность их удаления. Для этого предусмотрено два способа. Чтобы попробовать первый, щелкните на поле окна правой кнопкой мыши. Появится диалоговое окно, показанное на рис. 4.6. Если ввести значение индекса в поле Remove (Удалить) и щелкнуть на ОК. программа сотрет указанный элемент массива. Эта операция полностью отменяет результат вставки элемента - элемент удаляется, а массив сжимается. При желании можно установить опцию Remove All (Удалить все). Уж тут-то программа постарается и действительно удалит все элементы массива, но сам объект-массив останется.

Рис. 4.6. Диалоговое окно Remove from Array позволяет удалять элементы из массива

9.9.20. Объявление и инициализация массива
Теперь, конечно, вы полюбопытствуете, как же программируются все эти фокусы с массивом. Все, оказывается, на удивление просто (как, впрочем, бывает со всяким фокусом). Сначала программа объявляет объект-массив как член данных класса представления:
CUIntArray array;
Затем в конструкторе класса представления программа инициализирует массив из десяти элементов:
array.SetSize(10, 5);
Функция SetSize() принимает в качестве аргументов исходное количество элементов и инкремент приращения размера - количество элементов, которые "пристраиваются" к массиву каждый раз, когда для включения нового элемента не хватает существующей размерности. В принципе, обращаться к функции SetSize() совсем необязательно. Однако по умолчанию MFC будет наращивать размер массива порциями по одному элементу, т.е. при каждом включении нового элемента будет происходить обращение к операционной системе за новой порцией памяти, а это замедляет работу программы (хотя, если у вас выполняется достаточно серьезная обработка данных, прежде чем они будут записаны в массив, вы этого замедления и не почувствуете). Если вы не слишком обременяете программу включением новых элементов в массив, поскольку память вам дороже, вообще забудьте о функции SetSize(). Если же, наоборот, вы очень часто включаете в массив новые данные, а размер памяти не играет такой уж важной роли, используйте SetSize() и установите разумное значение инкремента приращения длины массива - это ускорит работу приложения, поскольку реже придется "упрашивать" операционную систему "оказать" программе услугу - выделить "кусочек" памяти.

9.9.21. Добавление элементов в массив
После того как размер массива установлен, программа ожидает, когда же пользователь соизволит щелкнуть кнопкой мыши - все равно какой, левой или правой. Когда это наконец произойдет, программа возьмется за дело - выведет на экран соответствующее диалоговое окно и обработает данные, которые будут в него введены. В листинге 4.1 представлен текст функции OnLButtonDown() приложения Array Demo, которая отрабатывает щелчок левой кнопкой мыши.
Листинг 4.1. Функция CArrayView::OnLButtonDown()
void CArrayView::OnLButtonDown(UINT nFlags, CPoint point)
{
ArrayAddDlg dialog(this);
dialog.m_index = 0;
dialog.m_value = 0;
dialog.m_radio = 0;
intresult = dialog.DoModal();
if (result == IDOK)
{
if (dialog.m_radio == 0)
array.SetAtGrow(dialog.m_index, dialog.m_value);
else if(dialog.m_radio==1)
array.lnsertAt(dialog.m_index, dialog.m_value, 1);
else
array.Add(dialog.m_value); Invalidate();
}
CView::OnLButtonDown(nFlags, point);

}
Первым делом, в функции создается объект и инициализируется диалоговое окно. Если пользователь завершает манипуляции в окне, щелкнув на кнопке OK, функция OnLButtonDown() анализирует значение переменной m_radiо - члена класса диалогового окна. Значение 0 означает, что был выбран первый переключатель (Set), 1 - второй переключатель (Insert), 2 - третий (Add).
Если пользователь пожелал установить значение некоторого элемента массива, программа обращается к функции SetAtGrow() и передает ей в качестве аргумента индекс в массиве и новое значение элемента. В отличие от SetAt(), которая может использовать только индекс, соответствующий текущему размеру массива, функция SetAtGrow() может при необходимости растянуть массив. Это приходится делать в том случае, если заданный индекс превышает максимальный для текущего состояния массива. Именно так произошло, когда вы выбрали установку элемента с индексом 20, а в массиве было всего 11 элементов, т.е. максимальный индекс был равен 10.
Когда пользователь выбирает переключатель Insert, программа вызывает функцию InsertAt() и также передает ей в качестве аргумента индекс в массиве и значение элемента. Это приводит к формированию нового элемента, который вставляется в массив соответственно заданному значению индекса, причем остальные элементы сдвигаются. И наконец, если выбран переключатель Add, программа вызывает функцию Add(), которая добавляет элемент в конец массива. У этой функции единственный аргумент - значение нового элемента. Вызов функции Invalidate() заставляет операционную систему обновить изображение в окне приложения.

9.9.22. Последовательное чтение элементов массива
Для того чтобы пользователь мог увидеть на экране результаты своих манипуляций, функция ОnDraw
() приложения Array Demo считывает значения элементов массива и выводит их на экран. Текст этой функции представлен в листинге 4.2.
Листинг 4.2. Функция CArrayView::OnDraw()
void CArrayView::OnDraw(CDC* pDC)
{
CArrayDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Считывание высоты текущего шрифта.
TEXTMETRIC textMetric;
pDC->GetTextMetrics(&textMetric);
int fontHeight = textMetric.tmHeight;
// Считывание размера массива.
int count = array.GetSize();
int displayPos = 10;
// Вывод на экран данных из массива.
for(int x=0; x<count; ++x)
{
UINT value = array.GetAt(x);
char s[81];
wsprintf(s, "Element%d contains the value %u.", x, value);
pDC->TextOut(10, displayPos, s);
displayPos += fontHeight;
}
}
В этой функции сначала считывается высота текущего шрифта, чтобы определить интервал между строками вывода элементов массива на экране. Затем считывается количество элементов в массиве, для чего вызывается функция GetSize(). И наконец программа использует счетчик элементов для организации цикла for, в котором с помощью функции GetAt() считываются значения элементов массива. При этом индекс - переменная цикла и одновременно аргумент вызова GetAt() - заставляет в каждом новом цикле обращаться к следующему элементу. Для вывода на экран программа преобразует числовое значение в текст.

9.9.23. Удаление элементов из массива
Поскольку приложение задумано таким образом, что диалоговое окно удаления вызывается после щелчка правой кнопкой мыши, именно с функции OnRButtonDown() и начинается процедура удаления. Текст этой функции представлен в листинге 4.3.
Листинг 4.3. Функция САrrауView::OnRButtonDown()
void CArrayView::OnRButtonDown(UINT nFlags, CPoint point)
{
ArrayRemoveDlg dialog(this);
dialog.m_remove = 0;
dialog.m_removeAII = FALSE;
int result = diаIog.DoModaI();
if (result == IDOK)
{
if (dialog.m_removeAII)
array.RemoveAII();
else
array.RemoveAt(dialog.m_remove);
Invalidate();
}
CView::OnRButtonDown(nFlags, point);

}
В этой функции после вывода на экран диалогового окна анализируется значение переменной m_removeAll - члена класса диалогового окна. Значение TRUE свидетельствует о том, что пользователь установил соответствующий флажок в диалоговом окне и желает удалить все элементы массива. В этом случае программа вызывает функцию RemoveAll() - член класса массива. Иначе вызывается функция RemoveAt(), единственный аргумент которой - индекс удаляемого элемента. Вызов функции Invalidate() заставляет операционную систему обновить изображение в окне приложения после проведенных манипуляций.

9.9.24. Классы списков
В общем, списки - это несколько своеобразные, "изощренные" массивы. В классах списков MFC реализован один из видов списков - связные списки (linked lists). B таких списках для связей между последовательными элементами (для элементов списков часто используется термин узел - node) применяются указатели. Это отличает списки от чистых массивов, в которых элементы просто последовательно располагаются в памяти. Списки более пригодны для организации таких множественных структур данных, в которых приходится часто добавлять или исключать элементы. Эти операции в связных списках выполняются гораздо быстрее, причем разница в скорости особенно заметна при большом количестве элементов. Однако поиск элемента в списке протекает медленнее, чем в массиве, поскольку приходится последовательно двигаться по всем элементам, руководствуясь связями-указателями.
Прежде чем приступить к рассмотрению операций со списками, придется несколько пополнить свой словарь терминов. Голова списка (head) - это первый узел списка, а хвост (tail) - последний узел (рис. 4.7).


Рис.4.7. Связный список имеет голову, хвост и множество узлов между ними
Библиотека MFC располагает тремя классами для работы со списками: CObList (элементами множества в нем являются объекты), CPtList (элементами являются указатели) и CStringList (элементами являются текстовые строки - объекты класса CString). Все классы списков имеют аналогичные функции-члены, а различаются, в основном, только типом данных, которые они хранят в узлах. В табл. А представлены функции - члены классов списков - и дано их описание.
Таблица 4.2 Функции-члены классов списков

Шаблоны списков
Связанные списки - это еще один хороший пример программной конструкции, в которой удобно использовать шаблоны. В библиотеке Standard Template Library, существуют шаблоны списка и очереди. Но следует прислушаться к мнению разработчиков о том, что использовать классы списков MFC значительно проще, чем шаблоны.

9.9.25. Описание приложения List
Познакомившись с классами списков и их функциями-членами, можно посмотреть, как все это выглядит на практике в работающей программе. Для экспериментов можно выбрать приложение List. Запустив его, на экране появится окно, показанное на рис. 4.8. В него выведены параметры единственного узла, с которого начинается список. Каждый узел списка может хранить два параметра - оба типа целое.
Экспериментируя с приложением List, можно будет добавлять новые узлы или удалять существующие из списка. Для включения нового узла необходимо щелкнуть левой кнопкой мыши в окне приложения. Появится диалоговое окно Add Node, показанное на рис. 4.9. Введите в соответствующие поля значения двух параметров, которые будет хранить этот узел, и щелкните на ОК. Как только эта несложная операцию будет проделана, программа присоединит новый узел к хвосту списка и выведет в окно новое содержимое списка. Например, если в диалоговое окно были введены значения 55 и 65, то содержимое списка будет выглядеть так, как показано на рис. 4.10.
Можно также удалить узел из списка. Для этого щелкните правой кнопкой мыши, чтобы на экране появилось диалоговое окно Remove Node (рис. 4.11). Оно предоставляет пользователю не очень богатые возможности: ему придется выбрать, какой узел списка удалить - хвостовой или головной; третьего, к сожалению, не дано. Когда вы закроете это окно, щелкнув на OK, программа удалит заказанный узел и выведет на экран новое состояние списка.

Рис.4.8 Приложение List в исходном состоянии содержит список, в котором имеется только один узел

Рис.4.9. Щелчок левой кнопкой мыши приводит к появлению на экране диалогового окна Add Node

Рис. 4.10. Каждый узел списка хранит два числа

Рис. 4.11. Щелчок правой кнопкой мыши приводит к появлению на экране диалогового окна Remove Node, которое позволяет удалить узел списка

Если попытаться удалить узел из пустого списка, приложение выведет на экран окно с предупреждением. Если приложение не будет анализировать такую ситуацию, это может привести к аварийному завершению программы, которая попытается удалить несуществующий узел.

9.9.26. Объявление и инициализация списка
Объявление списка ничем не отличается от объявления любого другого типа данных. Просто необходимо включить имя класса, который нужно использовать, а за ним - идентификатор объекта. Например, в приложении List это объявление выглядит следующим образом:
CPtrList list;
Программа объявляет объект класса CPtrList. Этот класс содержит связный список указателей. Такой список может указывать на данные любого типа.
Хотя для инициализации пустого списка большого ума не надо, все-таки придется решить, на какой тип данных будут указывать указатели в узлах списка, т.е. нужно объявить структуру узла. Объявление этой структуры в приложении List выглядит, как представлено в листинге 4.4.
Листинг 4.4 Структура CNode
struct Cnode
{
int value1;
int value2;
};
Здесь узел объявлен как структура, содержащая два члена типа int. Но при желании можно создать структуру с любым набором членов. Для того чтобы включить узел в список, нужно воспользоваться оператором new, который обеспечит требуемое количество памяти для нового экземпляра структуры, а затем добавит указатель на этот экземпляр в список. Приложение List в начальном состоянии содержит список, в котором имеется единственный узел. Он формируется с помощью конструктора класса представления, как это представлено в листинге 4.5.
Листинг 4.5 Конструктор класса CMyListView
CMyListView::CMyListView()
{
CNode* pNode = new CNode;
pNode->value1 = 11;
pNode->value2 = 22;
list.AddTail(pNode);
}
Фрагмент текста программы, представленный в этом листинге, сначала формирует новый экземпляр структуры CNode, а затем устанавливает значения ее членов. Метод AddTail() класса списка добавляет узел в хвост списка. Поскольку в этот момент список пуст, то ему, в общем-то, все равно, куда будет добавлен новый узел - в голову или в хвост, т.е. с тем же успехом можно было обратиться и к методу AddHead(). В результате формируется список, в котором всего один узел - он же головной, он же и хвостовой.

9.9.27. Добавление узлов в список
Хотя, в принципе, узлы можно вставлять в любое место списка, самое простое - присоединять их либо к голове, либо к хвосту списка. В результате новый узел становится либо головным в списке, либо хвостовым. В приложении List диалоговое окно Add Node выводится на экран после щелчка левой кнопкой мыши, так что разобраться в происходящем поможет анализ функции OnLButtonDown(), текст которой представлен в листинге 4.6.
Листинг 4.6. Функция CMyListView::OnLButtonDown()
void CMyListView::OnLButtonDown(UINT nFlags, CPoint point)
{

// Сформировать и инициализировать диалоговое окно.
AddNodeDlg dialog;
dialog.m_value1 = 0;
dialog.m_value2 = 0;
// Вывести на экран диалоговое окно.
int result = diаlog.DoModa I ();
// Если пользователь щелкнул на кнопке ОК...
if (result == IDOK)
{

// Сформировать и инициализировать новый узел.
CNode* pNode = new CNode;
pNode->value1 = diаlog.m_value1;
pNode->value2 = dialog.m_value2;
// Вставить узел в список.
list.AddTail(pNode);
// Перерисовать окно.
lnvalidate();

}
CView::OnLButtonDown(nFlags, point);

}
Здесь после вывода на экран диалогового окна программа ждет, когда же пользователь закроет его, щелкнув на кнопке ОК. Если это произошло, программа создает и инициализирует новый узел точно так, как первый узел в конструкторе класса представления. Включение нового узла в список, как и в первом случае, производится функцией AddTail().

9.9.28. Удаление узла из списка
Процедура удаления может быть простой или несколько усложненной - все зависит от того, как выбирать удаляемый узел. Так же, как и при включении узла, операция с произвольным узлом списка потребует, в первую очередь, локализовать искомый узел и получить его позицию в списке. Здесь для простоты программа позволяет пользователю выбрать один из двух вариантов - удалить головной узел или хвостовой. Соответствующий фрагмент программы представлен в листинге 4.7.
Листинг 4.7. Функция CMyListView::OnRButtonDown()
void CMyListView::OnRButtonDown(UINT nFlags, CPoint point)
{
// Сформировать и инициализировать диалоговое окно.
RemoveNodeDlg dialog;
dialog.m_radio = 0;
// Вывести на экран диалоговое окно.
int result = diаIog.DoModal();
// Если пользователь щелкнул на кнопке ОК...
if (result == IDOK)
{
CNode* pNode;
// Проверить, не пустой ли список.
if (list. lsEmpty())
MessageBox("No nodes to delete.");
else
{
// Удалить заданный узел,
if (dialog.m_radio == 0)
pNode = (CNode*)list.RemoveHead();
else
pNode = (CNode*) list.RemoveTail();
// Уничтожить объект узла и перерисовать окно,
delete pNode;
Invalidate();
}
}
CView::OnRButtonDown(nFlags, point);
}
Как и в предыдущем случае, после вывода на экран диалогового окна программа ждет, когда же пользователь закроет его, щелкнув на кнопке ОК. А после этого анализируется, какой выбор сделал пользователь - удалять хвостовой или головной узел. Если был выбран переключатель Remove Head (Удалить в голове), то переменная m_radiо - член класса диалогового окна - будет равна 0. Соответственно программа обратится к методу RemoveHead() класса списка. В противном случае будет вызвана функция RemoveTail(). Обе функции возвращают указатель на удаленный узел. Но прежде, чем приступать к экзекуции списка, нужно удостовериться, что объект экзекуции на месте. Обратите внимание на то, что перед анализом состояния переключателей диалогового окна в программе стоит вызов функции lsEmpty() и анализ возвращаемого ею значения. Если в списке нет узлов, экзекуция отменяется.

9.9.29. Классы ассоциированных списков
Для создания таблиц просмотра содержимого коллекций MFC предоставляет в распоряжение программиста классы ассоциированных списков. Например, при необходимости можно преобразовать с их помощью цифры в слова, представляющие соответствующие числа. Таким образом, можно использовать цифру 1 в качестве ключа для поиска слова один. Для решения такого рода задач классы ассоциированных списков (mapped classes) являются идеальным инструментом. Именно благодаря наличию в MFC таких классов можно использовать множество типов данных в качестве ключей и значений.
Набор классов ассоциированных списков в MFC включает CMapPtrToPtr, CMapPtrToWord, CMapStringToOb, CMapStringToPtr, CMapStringToString, CMapWordToOb и CMapWordToPtr. Первый тип данных в имени класса — это тип данных ключа, а второй — тип данных значения. Например, CMapStringToOb использует строковую переменную как ключ, а объект как значение; CMapStringToString— класс, который мы будем рассматривать в учебном приложении этого раздела, — использует строковую переменную и в качестве ключа, и в качестве значения. Все классы ассоциированных списков построены по одному принципу и имеют совершенно аналогичные методы, перечисленные в табл. 4.2.
Таблица 4.2. Методы классов ассоциированных списков

9.9.30. Описание приложения Map
Учебное приложение Map, которое рассматривается в этом разделе, выводит содержимое карты ассоциации и позволяет пользователю извлекать значения из карты, задавая определенный ключ. Непосредственно после запуска программа выводит окно, показанное на рис. 4.12.

Рис 4.12 Приложение Map выводит содержимое
карты ассоциации – объекта класса
В окне представлено содержимое объекта класса ассоциированного списка. Здесь цифры являются ключами, определяющими доступ к словам, которые в «словесной» форме представляют соответствующие числа. Для того, чтобы вытащить из карты (объекта класса) некоторое значение, щелкните на поле окна мышью. Появится диалоговое окно, показанное на рис.4.13. Введите значение ключа в поле Key и щелкните на OK. Программа найдет соответствующую ключу величину – слово-число – и выведет его в другом окне сообщения (рис.4.14).

Рис.4.13 Диалоговое окно Get Map Value позволяет выполнять поиск соответствия между заданным значением ключа и величинами, хранящимися в карте изображений

Рис. 4.14 В этом окне сообщения выводится соответствующая величина, найденная в карте отображения


9.9.31. Объявление и инициализация карты ассоциации
В исходном состоянии карта ассоциации приложения Map состоит из десяти элементов. Объект класса ассоциированного списка объявляется как член данных класса представления:
CMapStringToString map;
Это объект класса CMapStringToString, в котором используется строковая переменная и в качестве ключа, и в качестве значения.
Само по себе объявление объекта класса не заполняет его данными. Сделать это нужно отдельно, что и выполняется в конструкторе класса представления приложения Map. Соответствующий фрагмент программы представлен в листинге 4.8.
Листинг 4.8. Конструктор класса CMapView
CMapView::CMapView()
{
map. SetAt("1", "One");
map. SetAt("2", "Two");
map. SetAt("3", "Three");
map. SetAt("4", "Four");
map. SetAt("5", "Five");
map. SetAt("6", "Six");
map. SetAt("7", "Seven");
map. SetAt("8", "Eight");
map. SetAt("9", "Nine");
map. SetAt("10", "Ten");
}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: