Доступ ко всем членам коллекции
Для доступа к своим элементам классы коллекций массивов MFC (как шаблонные, так и нешаблонные) используют индексы. Для описания в заданной позиции в коллекции классы коллекций списков и схем MFC (как шаблонные, так и нешаблонные) используют индикатор типа POSITION . Чтобы получить доступ к одному или нескольким членам этих коллекций, сначала следует инициализировать индикатор позиции, а затем повторно передавать эту позицию в коллекцию с запросом на возврат следующего элемента. Коллекция не отвечает за поддержание сведений о состоянии хода выполнения итерации. Эта информация хранится в индикаторе позиции. Однако, принимая во внимание конкретную позицию, коллекция отвечает за возврат следующего элемента.
В приведенных далее процедурах показана итерация в трех основных типах коллекций в MFC.
Итерация массива
Используйте последовательные номера индекса с функцией-членом
GetAt
.CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
В этом примере используется массив типизированных указателей, который содержит указатели на объекты
CPerson
. Массив является производным от классаCObArray
, одного из нешаблонных предопределенных классов.GetAt
возвращает указатель на объектCPerson
. Для классов коллекций типизированных указателей (массивов или списков) первый параметр указывает базовый класс, второй параметр указывает тип для хранения.Класс
CTypedPtrArray
также перегружает оператор [ ] , чтобы можно было использовать обычный синтаксис массива для доступа к элементам массива. Альтернативой инструкции в теле приведенного выше циклаfor
являетсяCPerson *thePerson = myArray[i];
Этот оператор существует как в, так
const
и в версиях, отличныхconst
от версии. Версияconst
, которая вызывается дляconst
массивов, может отображаться только в правой части инструкции назначения.
Итерация списка
Для прохода по списку используйте функции-члены
GetHeadPosition
иGetNext
:CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
В этом примере используется список типизированных указателей, который содержит указатели на объекты
CPerson
. Объявление списка напоминает объявление для массива в процедуре Итерация массива , но является производным от классаCObList
.GetNext
возвращает указатель на объектCPerson
.
Итерация схемы
Используйте
GetStartPosition
для перехода в начало схемы иGetNextAssoc
для повторного получения следующего ключа и значения из схемы, как показано в следующем примере.CMap<CString, LPCTSTR, CPerson *, CPerson *> myMap; CPerson myPerson; myMap.SetAt(_T("Bill"), &myPerson); POSITION pos = myMap.GetStartPosition(); while (pos != NULL) { CPerson *pPerson; CString string; // Get key (string) and value (pPerson) myMap.GetNextAssoc(pos, string, pPerson); // Use string and pPerson }
В этом примере применяется шаблон простой схемы (а не коллекция типизированных указателей), использующий ключи
CString
и сохраняющий указатели на объектыCPerson
. При использовании функций доступа, таких какGetNextAssoc
, класс предоставляет указатели на объектыCPerson
. При использовании одной из коллекций нешаблонных схем необходимо привести возвращенный указательCObject
к указателю наCPerson
.Примечание.
При работе с нешаблонными схемами компилятору требуется ссылка на указатель
CObject
в последнем параметре наGetNextAssoc
. При воде данных необходимо привести указатели к этому типу, как показано в следующем примере.Шаблонное решение проще в использовании и помогает обеспечить более высокий уровень безопасности типов. Как видно из примера ниже, нешаблонный код более сложен.
CMapStringToOb myMap; // A nontemplate collection class CPerson myPerson; myMap.SetAt(_T("Bill"), &myPerson); POSITION pos = myMap.GetStartPosition(); while (pos != NULL) { CPerson *pPerson; CString string; // Gets key (string) and value (pPerson) myMap.GetNextAssoc(pos, string, (CObject *&)pPerson); ASSERT(pPerson->IsKindOf(RUNTIME_CLASS(CPerson))); // Use string and pPerson ... }
Дополнительные сведения см. в разделе Удаление всех объектов из коллекции CObject.