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
Déclarez une variable du type de classe de collection. Par exemple :
CList<int, int> m_intList;
Appelez la fonction membre de l’objet de la collection. Par exemple :
m_intList.AddTail(100); m_intList.RemoveAll();
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, UINT
et DWORD
CString
. 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 :
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.
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
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ésCObject
. Une collectionCObList
est définie pour contenir les pointeurs versCObject
. Lorsque vous récupérez un objet dans la liste, vous devrez peut-être convertir le résultat en type approprié puisque les fonctionsCObList
retournent des pointeurs versCObject
. Par exemple, si vous stockez les objetsCPerson
d'une collectionCObList
, vous devrez convertir un élément récupéré en pointeur vers un objetCPerson
. L’exemple suivant utilise une collectionCObList
pour gérer les objetsCPerson
: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
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 objetsCPerson
, vous pourrez ajouter des fonctions wrapperAddHeadPerson
etGetHeadPerson
, 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 fonctionGetHeadPerson
, 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.