Comment : définir une collection de type sécurisé

Cet article explique comment créer des collections de types cohérents pour vos propres types de données. Les sujets abordés sont les suivants :

La bibliothèque MFC fournit les collections de type sécurisé prédéfinies basées sur des modèles C++. Étant donné qu'il s'agit de modèles, ces classes offrent une cohérence des types et simplifient l'utilisation sans conversion de type, ainsi que bien d'autres tâches liées à l'utilisation d'une classe non basée sur un modèle. L’exemple MFC COLLECT illustre l’utilisation de classes de collection basées sur des modèles dans une application MFC. En général, utilisez ces classes lorsque vous entrez un nouveau code de collections.

Utilisation de classes basées sur des modèles pour le type Coffre ty

Pour utiliser des classes basées sur des modèles

  1. Déclarez une variable du type de classe de collection. Par exemple :

    CList<int, int> m_intList;
    
  2. Appelez la fonction membre de l’objet de la collection. Par exemple :

    m_intList.AddTail(100);
    m_intList.RemoveAll();
    
  3. Si nécessaire, implémentez les fonctions d’assistance et serializeElements. Pour plus d’informations sur l’implémentation de ces fonctions, consultez Implémentation des fonctions d’assistance.

Cet exemple illustre la déclaration d'une liste d'entiers. Le premier paramètre de l'étape 1 est le type de données stockées en tant qu'éléments dans la liste. Le deuxième paramètre spécifie la façon dont les données doivent être passées à des fonctions membres de la classe de collection, telles que Add et GetAt.

Implémentation des fonctions d’assistance

Les classes de collection basées sur les modèles CArray, CList et CMap utilisent cinq fonctions d’assistance globales que vous pouvez personnaliser autant que nécessaire pour votre classe de collection dérivée. Pour plus d’informations sur ces fonctions d’assistance, consultez les helpers de classe de collection dans la référence MFC. L’implémentation de la fonction de sérialisation est nécessaire pour la plupart des utilisations de classes de collection basées sur un modèle.

Sérialisation d’éléments

Les classes CArray, CList et CMap appellent SerializeElements pour stocker des éléments de collection ou pour la lecture d’une archive.

L'implémentation par défaut de la fonction d'assistance de SerializeElements effectue une écriture de bits sur les objets de l'archive, ou une lecture au niveau de l'archivage des objets, selon que les objets sont stockés ou extraits de l'archive. Remplacez SerializeElements si cette opération n'est pas appropriée.

Si la collection contient des objets dérivés CObject et que vous utilisez la macro IMPLEMENT_SERIAL dans l’implémentation de la classe d’éléments de collection, vous pouvez tirer parti des fonctionnalités de sérialisation intégrée dans CArchive et 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);
   }
}

Opérateurs d’insertion surchargés pour CArchive l’appel CObject::Serialize (ou remplacement de cette fonction) pour chaque CPerson objet.

Utilisation de classes de collection nontemplate

MFC gère également des classes de collection introduites avec la version 1.0 de MFC. Ces classes ne sont pas basées sur les modèles. Ils peuvent être utilisés pour contenir des données des types CObject*pris en charge, UINTet DWORDCString. Vous pouvez utiliser ces collections prédéfinies (comme CObList) pour gérer les collections de tous les objets dérivés de CObject. MFC fournit également d’autres collections prédéfinies pour contenir des types primitifs tels que UINT des pointeurs vides (void*). Toutefois, il est souvent pratique de définir vos propres collections de types cohérents pour stocker des objets de plusieurs classes spécifiques et ses dérivés. Notez que l’utilisation des classes de collection non basées sur des modèles nécessite plus de travail que l’utilisation des classes générées à partir de modèle.

Il existe deux manières de créer des collections de types cohérents avec les collections basées sur les modèles :

  1. Utilisez des collections non basées sur les modèles, avec la conversion de type, si nécessaire. Il s'agit de l'approche la plus simple.

  2. Dérivez ou étendez une collection de types cohérents non basés sur des modèles.

Pour utiliser des collections non basées sur des modèles avec la conversion de type

  1. Utilisez directement l'une des classes basées sur des modèles, telles que CWordArray.

    Par exemple, vous pouvez créer CWordArray et lui ajouter toutes les valeurs 32 bits avant de les récupérer. Il n'y a rien d'autre à faire. Utilisez uniquement la fonctionnalité prédéfinie.

    Vous pouvez également utiliser une collection prédéfinie, par exemple CObList, pour conserver tous les objets dérivés CObject. Une collection CObList est définie pour contenir les pointeurs vers CObject. Lorsque vous récupérez un objet dans la liste, vous devrez peut-être convertir le résultat en type approprié puisque les fonctions CObList retournent des pointeurs vers CObject. Par exemple, si vous stockez les objets CPerson d'une collection CObList, vous devrez convertir un élément récupéré en pointeur vers un objet CPerson. L’exemple suivant utilise une collection CObList pour gérer les objets CPerson :

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

    Cette technique d'utilisation d'un type de collection prédéfini et de la conversion si nécessaire peut être adéquate pour vos besoins en matière de collection. Si vous avez d'une fonctionnalité avancée ou de la cohérence des types, utilisez une classe basée sur un modèle, ou suivez la procédure ci-après.

Pour dériver et étendre une collection de types cohérents non basés sur des modèles

  1. Faites dériver votre propre classe de collection de l'une des classes basées sur des modèles prédéfinis.

    Lorsque vous dérivez votre classe, vous pouvez ajouter des fonctions wrapper de type cohérent pour fournir une interface de type cohérent aux fonctions existantes.

    Par exemple, si vous avez dérivé une liste CObList pour gérer les objets CPerson, vous pourrez ajouter des fonctions wrapper AddHeadPerson et GetHeadPerson, comme indiqué ci-dessous.

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

    Ces fonctions wrapper fournissent un mode de type cohérent pour ajouter et récupérer des objets CPerson de la liste dérivée. Vous pouvez voir que pour la fonction GetHeadPerson, vous encapsulez simplement la conversion de type.

    Vous pouvez également ajouter une nouvelle fonctionnalité en définissant de nouvelles fonctions qui étendent les capacités de la collection plutôt que de juste encapsuler les fonctionnalités existantes en types cohérents. Par exemple, l’article Suppression de tous les objets d’une collection CObject décrit une fonction pour supprimer tous les objets contenus dans une liste. Cette fonction peut être ajoutée à cette classe dérivée comme une fonction membre.

Voir aussi

Regroupements