Memorizzazione e caricamento di CObjects tramite un archivio
L'archiviazione e il caricamento CObject
di tramite un archivio richiedono considerazioni aggiuntive. In alcuni casi, è necessario chiamare la Serialize
funzione dell'oggetto , dove l'oggetto CArchive
è un parametro della Serialize
chiamata, anziché usare l'operatore << o >> di CArchive
. Il fatto importante da tenere presente è che l'operatore CArchive
>> costruisce in CObject
memoria in CRuntimeClass
base alle informazioni scritte in precedenza nel file dall'archivio di archiviazione.
Pertanto, se si usano gli CArchive
<< operatori e >> , invece di chiamare Serialize
, dipende dal fatto che sia necessario l'archivio di caricamento per ricostruire dinamicamente l'oggetto in base alle informazioni archiviate CRuntimeClass
in precedenza. Usare la Serialize
funzione nei casi seguenti:
Quando si deserializza l'oggetto, si conosce in anticipo la classe esatta dell'oggetto.
Quando si deserializza l'oggetto, la memoria è già allocata.
Attenzione
Se si carica l'oggetto usando la Serialize
funzione , è necessario archiviare anche l'oggetto usando la Serialize
funzione . Non archiviare usando l'operatore CArchive
<< e quindi caricare usando la Serialize
funzione o archiviare usando la funzione e quindi caricare usando CArchive >>
l'operatore Serialize
.
L'esempio seguente illustra i casi:
class CMyObject : public CObject
{
// ...Member functions
public:
CMyObject() {}
virtual void Serialize(CArchive &ar);
// Implementation
protected:
DECLARE_SERIAL(CMyObject)
};
class COtherObject : public CObject
{
// ...Member functions
public:
COtherObject() {}
virtual void Serialize(CArchive &ar);
// Implementation
protected:
DECLARE_SERIAL(COtherObject)
};
class CCompoundObject : public CObject
{
// ...Member functions
public:
CCompoundObject();
~CCompoundObject();
virtual void Serialize(CArchive &ar);
// Implementation
protected:
CMyObject m_myob; // Embedded object
COtherObject *m_pOther; // Object allocated in constructor
CObject *m_pObDyn; // Dynamically allocated object
//..Other member data and implementation
DECLARE_SERIAL(CCompoundObject)
};
IMPLEMENT_SERIAL(CMyObject, CObject, 1)
IMPLEMENT_SERIAL(COtherObject, CObject, 1)
IMPLEMENT_SERIAL(CCompoundObject, CObject, 1)
CCompoundObject::CCompoundObject()
{
m_pOther = new COtherObject; // Exact type known and object already
//allocated.
m_pObDyn = NULL; // Will be allocated in another member function
// if needed, could be a derived class object.
}
CCompoundObject::~CCompoundObject()
{
delete m_pOther;
}
void CCompoundObject::Serialize(CArchive &ar)
{
CObject::Serialize(ar); // Always call base class Serialize.
m_myob.Serialize(ar); // Call Serialize on embedded member.
m_pOther->Serialize(ar); // Call Serialize on objects of known exact type.
// Serialize dynamic members and other raw data
if (ar.IsStoring())
{
ar << m_pObDyn;
// Store other members
}
else
{
ar >> m_pObDyn; // Polymorphic reconstruction of persistent object
//load other members
}
}
In sintesi, se la classe serializzabile definisce un oggetto incorporato CObject
come membro, non è consigliabile usare gli CArchive
<< operatori e >> per tale oggetto, ma chiamare invece la Serialize
funzione . Inoltre, se la classe serializzabile definisce un puntatore a un CObject
oggetto (o un oggetto derivato da CObject
) come membro, ma costruisce questo altro oggetto nel proprio costruttore, è necessario chiamare Serialize
anche .