Serializace: Příprava serializovatelné třídy
K serializovatelné třídě se vyžaduje pět hlavních kroků. Jsou uvedené níže a jsou vysvětlené v následujících částech:
Odvození třídy z objektu CObject (nebo z některé třídy odvozené od
CObject
).Přepsání členové funkce Serializace
Použití DECLARE_SERIAL makra v deklaraci třídy.
Použití IMPLEMENT_SERIAL makra v souboru implementace pro vaši třídu.
Pokud voláte Serialize
přímo místo prostřednictvím >> operátorů CArchive, << poslední tři kroky nejsou vyžadovány pro serializaci.
Odvození třídy z objektu CObject
Základní serializační protokol a funkce jsou definovány ve CObject
třídě. Odvozením třídy ( CObject
nebo z třídy odvozené CObject
z ), jak je znázorněno v následující deklaraci třídy CPerson
, získáte přístup k serializačnímu protokolu a funkčnosti CObject
.
Přepsání členové funkce Serializace
Členská Serialize
funkce, která je definována CObject
ve třídě, je zodpovědná za skutečně serializaci dat potřebných k zachycení aktuálního stavu objektu. Funkce Serialize
má CArchive
argument, který používá ke čtení a zápisu dat objektu. CArchive objekt má členovou funkci, která označuje, IsStoring
zda Serialize
je uložen (zápis dat) nebo načítání (čtení dat). Pomocí výsledků jako vodítka IsStoring
vložíte data objektu CArchive
do objektu pomocí operátoru vložení (<<) nebo extrahujete data pomocí operátoru extrakce (>>).
Představte si třídu, která je odvozena a CObject
má dvě nové členské proměnné, typy CString
a WORD. Následující fragment deklarace třídy ukazuje nové členské proměnné a deklaraci pro přepsanou Serialize
členskou funkci:
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);
};
Přepsání členské funkce Serializace
Zavolejte verzi
Serialize
základní třídy, abyste se ujistili, že zděděná část objektu je serializována.Vložte nebo extrahujte členské proměnné specifické pro vaši třídu.
Operátory vložení a extrakce komunikují s archivní třídou ke čtení a zápisu dat. Následující příklad ukazuje, jak implementovat
Serialize
proCPerson
třídu deklarovanou výše: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; }
Můžete také použít členské funkce CArchive::Read a CArchive::Write pro čtení a zápis velkých objemů nezatypovaných dat.
Použití makra DECLARE_SERIAL
Makro DECLARE_SERIAL je vyžadováno v deklaraci tříd, které budou podporovat serializaci, jak je znázorněno zde:
class CPerson : public CObject
{
public:
DECLARE_SERIAL(CPerson)
Definování konstruktoru bez argumentů
MFC vyžaduje výchozí konstruktor při opětovném vytvoření objektů, protože jsou deserializovány (načteny z disku). Proces deserializace vyplní všechny členské proměnné hodnotami potřebnými k opětovnému vytvoření objektu.
Tento konstruktor může být deklarován jako veřejný, chráněný nebo soukromý. Pokud ji nastavíte jako chráněnou nebo soukromou, pomůže vám zajistit, aby ji používaly pouze funkce serializace. Konstruktor musí umístit objekt do stavu, který umožňuje jeho odstranění v případě potřeby.
Poznámka
Pokud zapomenete definovat konstruktor bez argumentů ve třídě, která používá DECLARE_SERIAL a IMPLEMENT_SERIAL makra, zobrazí se na řádku, kde se používá makro IMPLEMENT_SERIAL, upozornění kompilátoru bez výchozího konstruktoru.
Použití makra IMPLEMENT_SERIAL v souboru implementace
Makro IMPLEMENT_SERIAL slouží k definování různých funkcí potřebných při odvození serializovatelné třídy z CObject
. Toto makro použijete v souboru implementace (. CPP) pro vaši třídu. První dva argumenty makra jsou název třídy a název jeho bezprostřední základní třídy.
Třetím argumentem tohoto makra je číslo schématu. Číslo schématu je v podstatě číslo verze pro objekty třídy. Pro číslo schématu použijte celé číslo větší nebo rovno 0. (Nezaměňujte toto číslo schématu s terminologií databáze.)
Kód serializace MFC kontroluje číslo schématu při čtení objektů do paměti. Pokud číslo schématu objektu na disku neodpovídá číslu schématu třídy v paměti, knihovna vyvolá CArchiveException
výjimku , což programu brání v čtení nesprávné verze objektu.
Pokud chcete, aby členová Serialize
funkce mohla číst více verzí – tj. soubory napsané s různými verzemi aplikace – můžete použít hodnotu VERSIONABLE_SCHEMA jako argument pro IMPLEMENT_SERIAL makro. Informace o využití a příklad naleznete v GetObjectSchema
členské funkci třídy CArchive
.
Následující příklad ukazuje, jak použít IMPLEMENT_SERIAL pro třídu, CPerson
která je odvozena z CObject
:
IMPLEMENT_SERIAL(CPerson, CObject, 1)
Jakmile máte serializovatelnou třídu, můžete serializovat objekty třídy, jak je popsáno v článku Serializace: Serializace objektu.