Přístup ke všem členům kolekce
Třídy kolekce polí MFC ( založené na šablonách i ne ) používají indexy pro přístup k jejich prvkům. Třídy seznamů MFC a kolekcí map ( založené na šablonách i ne ) používají ukazatel typu POSITION k popisu dané pozice v kolekci. Pokud chcete získat přístup k jednomu nebo více členům těchto kolekcí, nejprve inicializujete indikátor pozice a pak tuto pozici opakovaně předáte kolekci a požádáte ji, aby vrátil další prvek. Kolekce neodpovídá za udržování informací o stavu o průběhu iterace. Informace se uchovávají v indikátoru pozice. Ale vzhledem k určité pozici je kolekce zodpovědná za vrácení dalšího prvku.
Následující postupy ukazují, jak iterovat nad třemi hlavními typy kolekcí poskytovaných v prostředí MFC:
Iterace pole
Používejte sekvenční indexová čísla s členovou
GetAt
funkcí:CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
V tomto příkladu se používá pole typového ukazatele, které obsahuje ukazatele na
CPerson
objekty. Pole je odvozeno z třídyCObArray
, jedna z netemplate předdefinované třídy.GetAt
vrátí ukazatel naCPerson
objekt. Pro třídy kolekce typových ukazatelů – pole nebo seznamy – první parametr určuje základní třídu; druhý parametr určuje typ, který se má uložit.Třída
CTypedPtrArray
také přetěžuje operátor [ ] tak, aby bylo možné použít vlastní syntaxi pole-dolní index pro přístup k prvkům pole. Alternativou k příkazu v textufor
výše uvedené smyčky jeCPerson *thePerson = myArray[i];
Tento operátor existuje v obou
const
verzích i v jinýchconst
verzích. Verzeconst
, která je vyvolána proconst
pole, se může zobrazit pouze na pravé straně příkazu přiřazení.
Iterace seznamu
Použijte členské funkce
GetHeadPosition
aGetNext
projděte si seznam:CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
V tomto příkladu se používá typový seznam ukazatelů, který obsahuje ukazatele na
CPerson
objekty. Deklarace seznamu se podobá té pro pole v postupu Iterace pole , ale je odvozena z třídyCObList
.GetNext
vrátí ukazatel naCPerson
objekt.
Iterace mapy
Slouží
GetStartPosition
k získání dalšího klíče a hodnoty z mapy na začátek mapy aGetNextAssoc
k opakovanému získání dalšího klíče a hodnoty, jak je znázorněno v následujícím příkladu: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 }
V tomto příkladu se používá jednoduchá šablona mapy (místo kolekce zadaných ukazatelů), která používá
CString
klíče a ukládá ukazatele naCPerson
objekty. Při použití přístupových funkcí, jakoGetNextAssoc
je , třída poskytuje ukazatele naCPerson
objekty. Pokud místo toho použijete některou z netemplatních kolekcí mapování, musíte vrácenýCObject
ukazatel přetypovat na ukazatel naCPerson
.Poznámka
Pro netemplatní mapy kompilátor vyžaduje odkaz na
CObject
ukazatel v posledním parametru naGetNextAssoc
. Při zadávání je nutné přetypovat ukazatele na tento typ, jak je znázorněno v dalším příkladu.Řešení šablony je jednodušší a pomáhá zajistit lepší bezpečnost typů. Netemplatní kód je složitější, jak vidíte tady:
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 ... }
Další informace naleznete v tématu Odstranění všech objektů v kolekci CObject.