Compartilhar via


Como fazer uma coleção fortemente tipada

Este artigo explica como criar coleções fortemente tipadas para seus tipos de dados. Os tópicos incluem:

A biblioteca Microsoft Foundation Class fornece coleções fortemente tipadas predefinidas com base em modelos C++. Como são modelos, essas classes ajudam a fornecer segurança de tipos e facilidade de uso sem a conversão de tipos e outro trabalho extra envolvido no uso de uma classe sem modelo para essa finalidade. O exemplo COLLECT do MFC demonstra o uso de classes de coleção baseadas em modelo em um aplicativo MFC. Em geral, use essas classes sempre que você escrever um novo código de coleções.

Como usar classes baseadas em modelo para segurança de tipos

Para usar classes baseadas em modelo

  1. Declare uma variável do tipo de classe de coleção. Por exemplo:

    CList<int, int> m_intList;
    
  2. Chame as funções de membro do objeto de coleção. Por exemplo:

    m_intList.AddTail(100);
    m_intList.RemoveAll();
    
  3. Se necessário, implemente as funções auxiliares e SerializeElements. Para informações sobre como implementar essas funções, confira Como implementar funções auxiliares.

Este exemplo mostra a declaração de uma lista de inteiros. O primeiro parâmetro na etapa 1 é o tipo de dados armazenados como elementos da lista. O segundo parâmetro especifica como os dados devem ser passados e retornados de funções membro da classe de coleção, como Add e GetAt.

Como implementar funções auxiliares

As classes de coleção baseadas em modelo CArray, CList e CMap usam cinco funções auxiliares globais que podem ser personalizadas conforme necessário para sua classe de coleção derivada. Para informações sobre essas funções auxiliares, confira Auxiliares de Classe de Coleção na Referência do MFC. A implementação da função de serialização é necessária para a maioria dos usos das classes de coleção baseadas em modelo.

Como serializar elementos

As CArray, CList e CMap chamam SerializeElements para armazenar elementos de coleção para lê-los de um arquivo morto.

A implementação padrão da função auxiliar SerializeElements faz uma gravação bit a bit dos objetos para o arquivo morto ou uma leitura bit a bit do arquivo morto para os objetos, dependendo se os objetos estão sendo armazenados ou recuperados do arquivo morto. Substitua SerializeElements se essa ação não for apropriada.

Se sua coleção armazenar objetos derivados de CObject e você usar a macro IMPLEMENT_SERIAL na implementação da classe de elemento de coleção, poderá aproveitar a funcionalidade de serialização interna CArchive e CObject:

CArray< CPerson, CPerson& > personArray;

template <> void AFXAPI SerializeElements <CPerson>(CArchive& ar,
   CPerson* pNewPersons, INT_PTR nCount)
{
   for (int i = 0; i < nCount; i++, pNewPersons++)
   {
      // Serialize each CPerson object
      pNewPersons->Serialize(ar);
   }
}

Os operadores de inserção sobrecarregados para CArchive chamam CObject::Serialize (ou uma substituição dessa função) para cada objeto CPerson.

Como usar classes de coleção sem modelo

O MFC também dá suporte às classes de coleção lançadas com o MFC versão 1.0. Essas classes não são baseadas em modelos. Elas podem ser usadas para conter dados dos tipos CObject*, UINT, DWORD e CString com suporte. Você pode usar essas coleções predefinidas (como CObList) para armazenar coleções de todos os objetos derivados de CObject. O MFC também fornece outras coleções predefinidas para conter tipos primitivos, como UINT e ponteiros nulos (void*). Porém, costuma ser útil definir suas coleções fortemente tipadas para armazenar objetos de uma classe mais específica e seus derivados. Observe que fazer isso com as classes de coleção não baseadas em modelos é mais trabalhoso do que usar as classes baseadas em modelo.

Há duas maneiras de criar coleções fortemente tipadas com as coleções sem modelo:

  1. Use as coleções sem modelo, com conversão de tipo, se necessário. Essa é a abordagem mais fácil.

  2. Derive e estenda uma coleção fortemente tipada sem modelo.

Para usar as coleções sem modelo com conversão de tipo

  1. Use uma das classes sem modelo, como CWordArray, diretamente.

    Por exemplo, você pode criar uma CWordArray e adicionar valores de 32 bits a ela, então recuperá-los. Não há mais nada a fazer. Basta usar a funcionalidade predefinida.

    Você também pode usar uma coleção predefinida, comoCObList, para manter todos os objetos derivados de CObject. Uma coleção CObList é definida para manter ponteiros para CObject. Ao recuperar um objeto da lista, talvez seja necessário converter o resultado no tipo adequado, já que as funções CObList retornam ponteiros para CObject. Por exemplo, se você armazenar objetos CPerson em uma coleção CObList, precisará converter um elemento recuperado para ser um ponteiro para um objeto CPerson. O seguinte exemplo usa uma coleção CObList para armazenar objetos CPerson:

    CPerson* p1 = new CPerson();
    CObList myList;
    
    myList.AddHead(p1);   // No cast needed
    CPerson* p2 = (CPerson*)myList.GetHead();
    

    Essa técnica de usar um tipo de coleção predefinido e converter conforme necessário pode ser adequada para muitas das suas necessidades de coleção. Se você precisar de mais funcionalidade ou mais segurança de tipos, use uma classe baseada em modelo ou siga o próximo procedimento.

Para derivar e estender uma coleção fortemente tipada sem modelo

  1. Derive sua classe de coleção de uma das classes sem modelo predefinidas.

    Ao derivar sua classe, você pode adicionar funções de wrapper fortemente tipadas para fornecer uma interface fortemente tipada às funções existentes.

    Por exemplo, se você tiver derivado uma lista de CObList para conter objetos CPerson, poderá adicionar as funções de wrapper AddHeadPerson e GetHeadPerson, conforme mostrado abaixo.

    class CPersonList : public CObList
    {
    public:
       void AddHeadPerson(CPerson* person)
       {
          AddHead(person);
       }
    
       const CPerson* GetHeadPerson()
       {
          return (CPerson*)GetHead();
       }
    };
    

    Essas funções de wrapper oferecem um modo fortemente tipado para adicionar e recuperar objetos CPerson da lista derivada. Você pode ver que, para a função GetHeadPerson, você está simplesmente encapsulando a conversão de tipo.

    Você também pode adicionar funcionalidades definindo novas funções que estendem os recursos da coleção, em vez de apenas encapsular a funcionalidade em wrappers fortemente tipados. Por exemplo, o artigo Como excluir todos os objetos em uma coleção CObject descreve uma função para excluir todos os objetos contidos em uma lista. Essa função pode ser adicionada à classe derivada como uma função de membro.

Confira também

Coleções