Armazenando e carregando CObjects por meio de um arquivo morto
Armazenar e carregar CObject
s por meio de um arquivo morto requer consideração extra. Em determinados casos, você deve chamar a função Serialize
do objeto, em que o objeto CArchive
é um parâmetro da chamada Serialize
, em vez de usar o operador << ou >> do CArchive
. O fato importante a ter em mente é que o operador CArchive
>> constrói CObject
na memória com base nas informações CRuntimeClass
gravadas anteriormente no arquivo pelo arquivo de armazenamento.
Portanto, se você usa os operadores CArchive
<< e >> operadores, em vez de chamarSerialize
, depende de se você precisa do arquivo de carregamento para reconstruir dinamicamente o objeto com base nas informações CRuntimeClass
armazenadas anteriormente. Use a função Serialize
nos seguintes casos:
Ao desserializar o objeto, você sabe a classe exata do objeto com antecedência.
Ao desserializar o objeto, você já tem memória alocada para ele.
Cuidado
Se você carregar o objeto usando a função Serialize
, também deverá armazenar o objeto usando a função Serialize
. Não armazene usando o operador CArchive
<< e carregue usando a função Serialize
ou armazene usando a função Serialize
e carregue usando o operador CArchive >>
.
O seguinte exemplo ilustra os casos:
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
}
}
Em resumo, se sua classe serializável definir um CObject
inserido como um membro, você não deverá usar os operadores CArchive
<< e >> para esse objeto, deverá chamar a função Serialize
. Além disso, se sua classe serializável definir um ponteiro para um CObject
(ou um objeto derivado de CObject
) como um membro, mas construir esse outro objeto em um construtor próprio, você também deverá chamar Serialize
.