Compartir a través de


Cómo: Crear una colección con seguridad de tipos

En este artículo, se explica cómo crear colecciones con seguridad de tipos para sus propios tipos de datos. Contenido de los temas:

La biblioteca MFC (Microsoft Foundation Class) proporciona colecciones con seguridad de tipos predefinidas basadas en plantillas de C++. Dado que son plantillas, estas clases permiten proporcionar seguridad de tipos y facilidad de uso sin la conversión de tipos y otros trabajos adicionales que implica el uso de una clase que no es plantilla para este propósito. En el ejemplo de MFC COLLECT, se muestra el uso de clases de colección basadas en plantillas en una aplicación MFC. Por lo general, estas clases se usan cada vez que se escribe el código de colecciones nuevas.

Uso de clases basadas en plantillas para la seguridad de tipos

Para utilizar clases basadas en plantillas

  1. Declare una variable del tipo de clase de colección. Por ejemplo:

    CList<int, int> m_intList;
    
  2. Llame a las funciones miembro del objeto de colección. Por ejemplo:

    m_intList.AddTail(100);
    m_intList.RemoveAll();
    
  3. Si es necesario, implemente las funciones auxiliares y SerializeElements. Para más información sobre cómo implementar estas funciones, consulte Implementación de funciones auxiliares.

En este ejemplo, se muestra la declaración de una lista de enteros. El primer parámetro del paso 1 es el tipo de datos almacenados como elementos de la lista. El segundo parámetro especifica cómo se pasan y devuelven los datos de las funciones miembro de la clase de colección, como Add y GetAt.

Implementación de funciones auxiliares

Las clases de colección basadas en plantillas CArray, CList y CMap usan cinco funciones auxiliares globales que se pueden personalizar según sea necesario para una clase de colección derivada. Para más información sobre estas funciones auxiliares, consulte Asistentes de clase de colección en la Referencia de MFC. La implementación de la función de serialización es necesaria para la mayoría de los usos de las clases de colección basadas en plantillas.

Serialización de elementos

Las clases CArray, CList y CMap llaman a SerializeElements para almacenar elementos de colección en un archivo o para leerlos desde él.

La implementación predeterminada de la función auxiliar SerializeElements realiza una escritura bit a bit de los objetos al archivo, o bien una lectura bit a bit del archivo a los objetos, en función de si los objetos se almacenan en el archivo o se recuperan de este. Invalide SerializeElements si esta acción no es adecuada.

Si la colección almacena objetos derivados de CObject y se utiliza la macro IMPLEMENT_SERIAL en la implementación del elemento de clase de colección, puede aprovechar la funcionalidad de serialización integrada en CArchive y 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);
   }
}

Los operadores de inserción sobrecargados para CArchive llaman a CObject::Serialize (o una invalidación de dicha función) para cada objeto CPerson.

Uso de clases de colección que no son plantillas

MFC también admite las clases de colección introducidas con la versión 1.0 de MFC. Estas clases no se basan en plantillas. Se pueden usar para contener datos de los tipos admitidos CObject*, UINT, DWORD, y CString. Puede usar estas colecciones predefinidas (como CObList) para contener colecciones de cualquier objeto derivado de CObject. MFC también proporciona otras colecciones predefinidas para contener tipos primitivos, como UINT y punteros void (void*). Sin embargo, en general, a menudo resulta útil definir sus propias colecciones con seguridad de tipos para contener objetos de una clase más específica y sus derivados. Tenga en cuenta que hacerlo con las clases de colección no basadas en plantillas implica más trabajo que usar las clases basadas en plantillas.

Hay dos maneras de crear colecciones con seguridad de tipos con las colecciones que no son plantillas:

  1. Use las colecciones que no son plantillas, con la conversión de tipos si es necesario. Este es el enfoque más sencillo.

  2. Derive y amplíe una colección con seguridad de tipos que no es plantilla.

Para usar las colecciones que no son plantillas con conversión de tipos

  1. Use directamente una de las clases que no son plantillas, como CWordArray.

    Por ejemplo, puede crear CWordArray, agregarle cualquier valor de 32 bits y, luego, recuperarlo. No es necesario hacer nada más. Solo tiene que usar la funcionalidad predefinida.

    También puede usar una colección predefinida, como CObList, para contener los objetos derivados de CObject. Se define una colección CObList para contener punteros a CObject. Al recuperar un objeto de la lista, es posible que tenga que convertir el resultado en el tipo adecuado, ya que las funciones CObList devuelven punteros a CObject. Por ejemplo, si almacena objetos CPerson en una colección CObList, debe convertir un elemento recuperado a fin de que sea un puntero a un objeto CPerson. En el ejemplo siguiente, se usa una colección CObList para contener objetos CPerson:

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

    Esta técnica de usar un tipo de colección predefinido y la conversión según sea necesario puede ser adecuada para muchas de las necesidades de la colección. Si necesita más funcionalidad o más seguridad de tipos, use una clase basada en plantillas o siga el procedimiento siguiente.

Para derivar y ampliar una colección con seguridad de tipos que no es plantilla

  1. Derive su propia clase de colección de una de las clases que no son plantillas predefinidas.

    Al derivar la clase, puede agregar funciones contenedoras con seguridad de tipos para proporcionar una interfaz con seguridad de tipos a las funciones existentes.

    Por ejemplo, si deriva una lista de CObList para contener objetos CPerson, puede agregar las funciones contenedoras AddHeadPerson y GetHeadPerson, tal como se muestra a continuación.

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

    Estas funciones contenedoras proporcionan una forma con seguridad de tipos para agregar y recuperar objetos CPerson de la lista derivada. Puede ver que, para la función GetHeadPerson, simplemente encapsula la conversión de tipos.

    También puede agregar una funcionalidad nueva si define funciones nuevas que amplían las capacidades de la colección en lugar de simplemente encapsular la funcionalidad existente en contenedores con seguridad de tipos. Por ejemplo, en el artículo Eliminación de todos los objetos de una colección CObject, se describe una función para eliminar todos los objetos contenidos en una lista. Esta función se puede agregar a la clase derivada como una función miembro.

Consulte también

Colecciones