Acceso a todos los miembros de una colección
Las clases de colección de matriz MFC (plantilla- basado y no — utilizan índices para obtener acceso a sus elementos. MFC muestra y asigna tipos de colección — plantilla- basado y no — usa una marca de posición escrito para describir una posición especificada de la colección. Para obtener acceso a uno o más miembros de estas colecciones, primero se inicializa el marcador de posición y después repetidamente pasa que colocar a la colección y la orders para devolver el elemento siguiente. La colección no es responsable de mantener información de estado sobre el progreso de la iteración. Dicha información se mantiene el marcador de posición. Pero, dada una posición determinada, la colección devuelve el siguiente elemento.
Los procedimientos siguientes muestran cómo iterar en los tres tipos principales de colecciones proporcionadas MFC:
Recorrer una matriz
Recorrer una lista
Recorrer un mapa
Para recorrer una matriz
Números de índice secuenciales de uso con la función miembro de 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 utiliza una matriz de tipo puntero que contiene punteros a objetos de CPerson . La matriz se deriva de la clase CObArray, una de las clases predefinidas segunda. GetAt devuelve un puntero a un objeto de CPerson . Para las clases de colección con tipo de puntero — matrices o listas — el primer parámetro especifica la clase base; el segundo parámetro especifica el tipo para almacenar.
La clase de CTypedPtrArray también sobrecarga el operador de ###[###]para poder utilizar la sintaxis habitual de subíndices de matriz para obtener acceso a los elementos de una matriz. Una alternativa a la instrucción en el cuerpo del bucle de for anteriormente son
CPerson* thePerson = myArray[i];
Este operador existe en const y las versiones no deconst . La versión de const , que se invoca para las matrices de const , sólo puede aparecer a la derecha de una instrucción de asignación.
Para recorrer una lista
Utilice las funciones GetHeadPosition y GetNext miembro para trabajar la manera en 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 utiliza una lista de tipo puntero para contener punteros a objetos de CPerson . La declaración de la lista se parece al correspondiente a la matriz en el procedimiento Para recorrer una matriz pero se deriva de la clase CObList. GetNext devuelve un puntero a un objeto de CPerson .
Para recorrer un mapa
Uso GetStartPosition de obtener al principio del mapa y de GetNextAssoc para obtener repetidamente la clave y el valor siguientes del mapa, como se muestra en el ejemplo siguiente:
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 utiliza una plantilla de asignación simple (en lugar de una colección de tipo puntero) que utiliza las teclas de CString y almacena punteros a objetos de CPerson . Cuando se usan funciones de acceso como GetNextAssoc, la clase proporciona punteros a objetos de CPerson . Si utiliza una de las colecciones de mapa que no es de plantilla en su lugar, debe convertir el puntero devuelto de CObject a un puntero a CPerson.
Nota
De segunda, el compilador requiere una referencia a un puntero de CObject en el parámetro pasado a GetNextAssoc.En la entrada, debe convertir los punteros a ese tipo, como se muestra en el ejemplo siguiente.
La solución de plantilla es más fácil y facilita una mayor seguridad de tipos. El código que no es de plantilla 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 objetos Todo en una colección de CObject.