Przechowywanie i ładowanie obiektów CObject za pomocą archiwum
Przechowywanie i ładowanie CObject
plików za pośrednictwem archiwum wymaga dodatkowej uwagi. W niektórych przypadkach należy wywołać Serialize
funkcję obiektu, gdzie CArchive
obiekt jest parametrem Serialize
wywołania, w przeciwieństwie do używania << operatora or >> obiektu CArchive
. Należy pamiętać, że CArchive
>> operator konstruuje CObject
element w pamięci na CRuntimeClass
podstawie informacji zapisanych wcześniej w pliku przez archiwum przechowywania.
W związku z tym, czy używasz CArchive
<< operatorów i>>, a nie wywoływania Serialize
, zależy od tego, czy potrzebujesz archiwum ładowania, aby dynamicznie odtworzyć obiekt na podstawie wcześniej przechowywanych CRuntimeClass
informacji. Serialize
Użyj funkcji w następujących przypadkach:
Podczas deserializacji obiektu wcześniej znasz dokładną klasę obiektu.
Podczas deserializacji obiektu masz już przydzieloną pamięć.
Uwaga
Jeśli załadujesz obiekt przy użyciu Serialize
funkcji, musisz również zapisać obiekt przy użyciu Serialize
funkcji . Nie należy przechowywać przy użyciu CArchive
<< operatora , a następnie ładować przy użyciu Serialize
funkcji lub przechowywać przy użyciu Serialize
funkcji, a następnie ładować za pomocą CArchive >>
operatora .
Poniższy przykład ilustruje przypadki:
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
}
}
Podsumowując, jeśli klasa z możliwością serializacji definiuje osadzony CObject
jako element członkowski, nie należy używać << CArchive
operatorów i >> dla tego obiektu, ale należy wywołać Serialize
funkcję. Ponadto jeśli klasa z możliwością serializacji definiuje wskaźnik do CObject
obiektu (lub obiektu pochodzącego z CObject
klasy ) jako elementu członkowskiego, ale tworzy ten inny obiekt we własnym konstruktorze, należy również wywołać metodę Serialize
.