Acessando todos os membros de uma coleção
As classes de coleção na matriz de MFC — baseado em e não — índices de uso para acessar seus elementos. As classes de coleção da lista e de mapa baseado MFC — e — não usam um indicador de tipo POSITION para descrever uma posição especificada na coleção. Para acessar um ou mais membros dessas coleções, você primeiro inicializa o indicador de posição e depois repetidamente passa essa posição à coleção e pede-a para retornar o próximo elemento. A coleção não é responsável por manter informações de estado sobre o progresso da iteração. Essa informação é mantida no indicador de posição. Mas, dada uma posição específica, a coleção é responsável para retornar o próximo elemento.
Os procedimentos a seguir mostram como iterar sobre os três tipos principais de coleções fornecidas com o MFC:
Iterando uma matriz
Iterando uma lista
Iterando um mapa
Para iterar uma matriz
Use números sequenciais de índice com a função de membro 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 exemplo usa uma matriz de ponteiro digitada que contém ponteiros para os objetos de CPerson . A matriz é derivada da classe CObArray, uma das classes predefinidas nontemplate. GetAt retorna um ponteiro para um objeto de CPerson . Para classes de coleção do tipo de ponteiro — matrizes ou listas — o primeiro parâmetro especifica a classe base; o segundo parâmetro especifica o tipo para armazenar.
A classe de CTypedPtrArray também sobrecarregar o operador de [] de forma que você possa usar a sintaxe normal de matriz- subscrito para acessar os elementos de uma matriz. Uma alternativa à instrução no corpo do loop anterior é de for
CPerson* thePerson = myArray[i];
Esse operador existe em const e não em versões deconst . A versão de const , que é chamada para matrizes de const , pode aparecer somente no lado direito de uma instrução de atribuição.
Para iterar uma lista
Use as funções de membro GetHeadPosition e GetNext para trabalhar sua maneira pela lista:
CTypedPtrList<CObList, CPerson*> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while(pos != NULL) { CPerson* thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
Este exemplo usa uma lista com tipo de ponteiro para conter ponteiros para os objetos de CPerson . A declaração de lista é semelhante ao da matriz no procedimento Para iterar uma matriz mas é derivada da classe CObList. GetNext retorna um ponteiro para um objeto de CPerson .
Para iterar um mapa
Uso GetStartPosition obter ao início do mapa e de GetNextAssoc para obter repetidamente a chave e o valor seguintes do mapa, como mostra o exemplo a seguir:
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 exemplo usa um modelo simples do mapa (em vez de uma coleção com tipo de ponteiro) que usa que CString fecha e armazena ponteiros para os objetos de CPerson . Quando você usar funções de acesso como, GetNextAssoca classe fornece ponteiros para os objetos de CPerson . Se você usar uma das coleções de mapa de nontemplate em vez disso, você deve converter o ponteiro retornado de CObject a um ponteiro para CPerson.
Dica
Para mapas de nontemplate, o compilador requer uma referência a um ponteiro de CObject no parâmetro do último a GetNextAssoc.Na entrada, você deverá converter os ponteiros para cada tipo, conforme mostrado no exemplo a seguir.
A solução de modelo é mais simples e ajudará proporcionam melhor segurança de tipo. O código de nontemplate é mais complicado, como você pode ver aqui:
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 obter mais informações, consulte Excluindo todos os objetos em uma coleção de CObject.