Acceso a todos los miembros de una colección
Las clases de colección de matriz MFC —tanto basadas en plantillas como no— usan índices para obtener acceso a sus elementos. Las clases de colección de listas y mapas MFC (tanto basadas en plantillas como no) usan un indicador de tipo POSITION para describir una posición dada dentro de la colección. Para obtener acceso a uno o más miembros de estas colecciones, primero se inicializa el indicador de posición, después se pasa esa posición repetidamente a la colección y luego se le pide que devuelva el elemento siguiente. La colección no es responsable de mantener la información de estado sobre el progreso de la iteración. Esta información se guarda en el indicador de posición. Pero, en una posición concreta, la colección es responsable de devolver el elemento siguiente.
Los procedimientos siguientes muestran cómo iterar en los tres tipos principales de colecciones proporcionadas por MFC:
Para recorrer en iteración una matriz
Use números de índice secuenciales con la función miembro
GetAt
:CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
Este ejemplo usa una matriz de puntero con tipo que contiene punteros a objetos
CPerson
. La matriz se deriva de la claseCObArray
, una de las clases predefinidas no basadas en plantillas.GetAt
devuelve un puntero a un objetoCPerson
. Para las clases de colección de puntero con tipo (matrices o listas), el primer parámetro especifica la clase base; el segundo parámetro especifica el tipo para almacenar.La clase
CTypedPtrArray
también sobrecarga el operador [ ] para poder usar la sintaxis habitual de subíndices de matriz para obtener acceso a los elementos de una matriz. Una alternativa a la instrucción del cuerpo del buclefor
anterior esCPerson *thePerson = myArray[i];
Este operador existe en las versiones
const
y noconst
. La versiónconst
, que se invoca para las matricesconst
, puede aparecer solo en el lado derecho de una instrucción de asignación.
Para recorrer en iteración una lista
Use las funciones miembro
GetHeadPosition
yGetNext
para trabajar a su manera a través de la lista:CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
Este ejemplo usa una lista de puntero con tipo que contiene punteros a objetos
CPerson
. La declaración de la lista es similar a la de la matriz en el procedimiento Para recorrer en iteración una matriz pero se deriva de la claseCObList
.GetNext
devuelve un puntero a un objetoCPerson
.
Para recorrer en iteración un mapa
Use
GetStartPosition
para llegar al principio del mapa yGetNextAssoc
para obtener repetidamente la clave y el valor siguiente del mapa, como se muestra en el siguiente ejemplo: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 }
Este ejemplo usa una plantilla de mapa sencilla (en lugar de una colección de puntero con tipo) que usa claves de
CString
y almacena punteros a objetosCPerson
. Cuando usa las funciones de acceso comoGetNextAssoc
, la clase proporciona punteros a objetosCPerson
. Si en su lugar usa una de las colecciones de mapa que no está basada en plantillas, debe convertir el punteroCObject
devuelto en un puntero a unCPerson
.Nota:
Para los mapas que no están basados en plantillas, el compilador requiere una referencia a un puntero
CObject
en el último parámetro paraGetNextAssoc
. En la entrada, debe convertir los punteros a ese tipo, como se muestra en el siguiente ejemplo.La solución de plantilla es más sencilla y ayuda a proporcionar mejor seguridad de tipos. El código que no está basado en plantillas es más complicado, como puede ver aquí:
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 ... }
Para obtener más información, vea Eliminar todos los objetos de una colección CObject.