Accesso a tutti i membri di una raccolta
Le classi di raccolte di matrici di MFC, sia basate su modelli che non, usano indici per accedere ai loro elementi. Le classi di raccolte di liste e mappe di MFC, sia basate su modelli che non, usano un indicatore di tipo POSITION per descrivere una data posizione nella raccolta. Per accedere a uno o più membri di queste raccolte, è necessario innanzitutto inizializzare l'indicatore di posizione e poi passare ripetutamente quella posizione alla raccolta e chiederle di restituire l'elemento successivo. La raccolta non è responsabile di mantenere le informazioni di stato sull'avanzamento dell'iterazione. Tali informazioni vengono mantenute nell'indicatore di posizione. Tuttavia, data una particolare posizione, la raccolta è responsabile di restituire l'elemento successivo.
Le procedure seguenti mostrano come eseguire un'iterazione sui tre tipi principali di raccolte disponibili in MFC:
Per eseguire un'iterazione su una matrice
Usare numeri di indice sequenziali con la funzione membro
GetAt
:CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
In questo esempio si usa una matrice con puntatore tipizzato che contiene puntatori agli oggetti
CPerson
. La matrice è derivata dalla classeCObArray
, una delle classi predefinite non basate su modelli.GetAt
restituisce un puntatore a un oggettoCPerson
. Per le classi di raccolte con puntatore tipizzato, ovvero matrici o elenchi, il primo parametro specifica la classe base e il secondo specifica il tipo da memorizzare.La
CTypedPtrArray
classe esegue anche l'overload dell'operatore [ ] in modo da poter usare la sintassi di indice matrice personalizzata per accedere agli elementi di una matrice. Un'alternativa all'istruzione nel corpo del ciclofor
riportato sopra èCPerson *thePerson = myArray[i];
Questo operatore esiste in entrambe
const
le versioni e nonconst
. Laconst
versione, richiamata perconst
le matrici, può essere visualizzata solo sul lato destro di un'istruzione di assegnazione.
Per eseguire un'iterazione su un elenco
Usare le funzioni membro
GetHeadPosition
eGetNext
per percorrere l'elenco:CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
In questo esempio si usa un elenco con puntatore tipizzato che contiene i puntatori agli oggetti
CPerson
. La dichiarazione dell'elenco è simile a quella della matrice nella procedura Per eseguire un'iterazione su una matrice ma è derivata dalla classeCObList
.GetNext
restituisce un puntatore a un oggettoCPerson
.
Per eseguire un'iterazione su una mappa
Usare
GetStartPosition
per posizionarsi all'inizio della mappa eGetNextAssoc
per ottenere ripetutamente la chiave e il valore successivi dalla mappa, come mostrato nell'esempio seguente: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 }
In questo esempio si usa un semplice modello di mappa (anziché una raccolta con puntatore tipizzato) che usa chiavi
CString
e memorizza puntatori agli oggettiCPerson
. Quando si usano funzioni di accesso comeGetNextAssoc
, la classe fornisce i puntatori agli oggettiCPerson
. Se invece si usa una delle raccolte di mappe non basate su modelli, è necessario eseguire il cast del puntatoreCObject
restituito verso un puntatore aCPerson
.Nota
Per le mappe non basate su modelli, il compilatore richiede un riferimento a un puntatore
CObject
nell'ultimo parametro perGetNextAssoc
. In fase di input, è necessario eseguire il cast dei puntatori verso quel tipo, come mostrato nell'esempio successivo.La soluzione basata su modelli è più semplice e aiuta a garantire una maggiore indipendenza dai tipi. Il codice per la soluzione non basata su modelli è più complicato, come è possibile vedere qui:
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 ... }
Per altre informazioni vedere Eliminazione di tutti gli oggetti in una raccolta CObject.