Partager via


Sérialisation : définir une classe sérialisable

Cinq étapes principales sont requises pour rendre une classe sérialisable. Elles sont répertoriées ci-dessous et expliquées dans les sections suivantes :

  1. Dérivation de votre classe de CObject (ou d’une classe dérivée de CObject).

  2. Substitution de la fonction membre Serialize.

  3. Utilisation de la macro DECLARE_SERIAL dans la déclaration de classe.

  4. Définition d’un constructeur qui ne prend aucun argument.

  5. Utilisation de la macro IMPLEMENT_SERIAL dans le fichier d’implémentation de votre classe.

Si vous appelez Serialize directement plutôt que par le biais des >> opérateurs de << CArchive, les trois dernières étapes ne sont pas requises pour la sérialisation.

Dérivation de votre classe à partir de CObject

Le protocole et les fonctionnalités de base de sérialisation sont définis dans la classe CObject. En faisant dériver votre classe de CObject (ou une classe dérivée de CObject), comme indiqué dans la déclaration suivante de la classe CPerson, vous accédez au protocole de sérialisation et à la fonctionnalité CObject.

Substitution de la fonction membre Sérialiser

La fonction membre Serialize, définie dans la classe CObject, est chargée de la sérialisation réelle des données nécessaires pour capturer l'état actuel d'un objet. La fonction Serialize a un argument CArchive qu’elle utilise pour lire et écrire les données de l’objet. L’objet CArchive a une fonction membre, IsStoringqui indique si Serialize le stockage (écriture de données) ou le chargement (lecture de données). À l’aide des résultats d’un IsStoring guide, vous insérez les données de votre objet dans l’objet CArchive avec l’opérateur d’insertion (<<) ou extrayez des données avec l’opérateur d’extraction (>>).

Considérez une classe dérivée de CObject deux nouvelles variables membres, de types CString et WORD. Le fragment de déclaration de classe présente les variables membres et la déclaration de la fonction membre substituée de Serialize :

class CPerson : public CObject
{
public:
   DECLARE_SERIAL(CPerson)
   // empty constructor is necessary
   CPerson();
   virtual ~CPerson();

   CString m_name;
   WORD   m_number;

   void Serialize(CArchive& archive);
};

Pour remplacer la fonction membre Serialize.

  1. Appelez votre version de la classe de base de Serialize pour vérifier que la partie héritée de l'objet est sérialisée.

  2. Insérez ou extrayez les variables membres spécifiques à votre classe.

    Les opérateurs d'insertion et d'extraction interagissent avec la classe d'archive pour lire et écrire les données. L'exemple suivant montre comment implémenter Serialize pour la classe CPerson déclarée ci-dessus :

    void CPerson::Serialize(CArchive& archive)
    {
       // call base class function first
       // base class is CObject in this case
       CObject::Serialize(archive);
    
       // now do the stuff for our specific class
       if (archive.IsStoring())
          archive << m_name << m_number;
       else
          archive >> m_name >> m_number;
    }
    

Vous pouvez également utiliser les fonctions membres CArchive ::Read et CArchive ::Write pour lire et écrire de grandes quantités de données non typées.

Utilisation de la macro DECLARE_SERIAL

La macro DECLARE_SERIAL est requise dans la déclaration de classes qui prend en charge la sérialisation, comme indiqué ici :

class CPerson : public CObject
{
public:
   DECLARE_SERIAL(CPerson)

Définition d’un constructeur sans arguments

MFC requiert un constructeur par défaut lorsqu'il recrée les objets tels qu'ils sont désérialisés (chargés du disque). Le processus de désérialisation complète toutes les variables membres avec les valeurs requises pour recréer l’objet.

Ce constructeur peut être déclaré public, protégé ou privé. Si vous le protégez ou le rendez privé, vous vous assurez qu'il sera utilisé uniquement par les fonctions de sérialisation. Le constructeur doit mettre l'objet dans un état qui l'autorise à être supprimé, si nécessaire.

Remarque

Si vous oubliez de définir un constructeur sans arguments dans une classe qui utilise les macros DECLARE_SERIAL et IMPLEMENT_SERIAL, vous obtenez un avertissement du compilateur « aucun constructeur par défaut disponible » sur la ligne où la macro IMPLEMENT_SERIAL est utilisée.

Utilisation de la macro IMPLEMENT_SERIAL dans le fichier d’implémentation

La macro IMPLEMENT_SERIAL est utilisée pour définir les différentes fonctions nécessaires lorsque vous dérivez une classe sérialisable à partir de CObject. Utilisez la macro du fichier d'implémentation (.CPP) pour la classe. Les deux premiers arguments à la macro sont le nom de la classe et le nom de la classe de base immédiate.

Le troisième argument de la macro est un numéro de schéma. Le numéro de schéma est essentiellement le numéro de version des objets de la classe. Utilisez un entier supérieur ou égal à 0 pour le numéro de schéma. (Ne confondez pas le numéro de schéma avec la terminologie de base de données.)

Le code de sérialisation MFC vérifie le numéro de schéma lors de la lecture des objets en mémoire. Si le numéro de schéma de l'objet sur le disque ne correspond pas au numéro de schéma de la classe en mémoire, la bibliothèque lèvera CArchiveException, ce qui empêchera votre programme de lire une version incorrecte de l'objet.

Si vous souhaitez que votre Serialize fonction membre puisse lire plusieurs versions( c’est-à-dire des fichiers écrits avec différentes versions de l’application), vous pouvez utiliser la valeur VERSIONABLE_SCHEMA comme argument de la macro IMPLEMENT_SERIAL. Pour les informations d'utilisation et un exemple, consultez la fonction membre GetObjectSchema de la classe CArchive.

L’exemple suivant montre comment utiliser IMPLEMENT_SERIAL pour une classe, CPersonqui est dérivée de CObject:

IMPLEMENT_SERIAL(CPerson, CObject, 1)

Une fois que vous disposez d’une classe sérialisable, vous pouvez sérialiser des objets de la classe, comme indiqué dans l’article Sérialisation : sérialisation d’un objet.

Voir aussi

Sérialisation