Accès à tous les membres d’une collection
Les classes de collection de tableau MFC (qu’elles soient ou non basées sur un modèle) utilisent des index pour accéder à leurs éléments. Les classes de collection de mappage et de liste MFC (qu’elles soient ou non basées sur un modèle) utilisent un indicateur de type POSITION pour décrire une position donnée dans la collection. Pour accéder à un ou plusieurs membres d’une collection de ce type, vous devez en premier lieu initialiser l’indicateur de position et passer plusieurs fois cette position à la collection et lui demander de retourner l’élément suivant. La collection n’est pas responsable du suivi des informations d’état de la progression de l’itération. Ces informations sont conservées dans l’indicateur de position. En revanche, pour une position donnée, la collection est chargée de retourner l’élément suivant.
Les procédures suivantes montrent comment itérer sur les trois principaux types de collection fournis avec MFC :
Pour itérer un tableau
Utilisez des numéros d’index séquentiels avec la fonction membre
GetAt
:CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
Cet exemple utilise un tableau de pointeurs typés qui contient des pointeurs vers des objets
CPerson
. Le tableau est dérivé de la classeCObArray
, l’une des classes prédéfinies non basées sur un modèle.GetAt
retourne un pointeur vers un objetCPerson
. Pour les classes de collection de pointeurs typés (tableaux ou listes), le premier paramètre spécifie la classe de base ; le deuxième paramètre spécifie le type à stocker.La
CTypedPtrArray
classe surcharge également l’opérateur [ ] afin que vous puissiez utiliser la syntaxe de tableau-indice habituelle pour accéder aux éléments d’un tableau. Plutôt que d’utiliser l’instruction dans le corps de la bouclefor
ci-dessus, voici une alternative :CPerson *thePerson = myArray[i];
Cet opérateur existe à la fois
const
dans les versions et les versions nonconst
. Laconst
version, appelée pourconst
les tableaux, ne peut apparaître que sur le côté droit d’une instruction d’affectation.
Pour itérer une liste
Utilisez les fonctions membres
GetHeadPosition
etGetNext
pour parcourir la liste :CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
Cet exemple utilise une liste de pointeurs typés destinée à contenir des pointeurs vers des objets
CPerson
. La déclaration de liste ressemble à celle du tableau de la procédure Pour itérer un tableau , sauf qu’elle est dérivée de la classeCObList
.GetNext
retourne un pointeur vers un objetCPerson
.
Pour itérer un mappage
Utilisez
GetStartPosition
pour atteindre le début du mappage etGetNextAssoc
pour obtenir plusieurs fois la clé et la valeur suivantes du mappage, comme le montre l’exemple suivant :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 }
Cet exemple utilise un modèle de mappage simple (et non une collection de pointeurs typés) qui utilise des clés
CString
et stocke des pointeurs vers des objetsCPerson
. Quand vous utilisez des fonctions d’accès, telles queGetNextAssoc
, la classe fournit des pointeurs vers des objetsCPerson
. Si, à la place, vous utilisez l’une des collections de mappages non basés sur un modèle, vous devez convertir le pointeurCObject
retourné en pointeur vers unCPerson
.Remarque
Pour les mappages non basés sur un modèle, le compilateur nécessite une référence à un pointeur
CObject
dans le dernier paramètre deGetNextAssoc
. En entrée, vous devez convertir vos pointeurs dans ce type, comme le montre l’exemple suivant.La solution avec modèle est plus simple et assure une meilleure sécurité de type. Le code sans modèle est plus compliqué, comme vous pouvez le constater ici :
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 ... }
Pour plus d’informations, consultez Suppression de tous les objets d’une collection CObject.