Сохранение и загрузка CObjects через архив
Для хранения и загрузки CObject
с помощью архива требуется дополнительное внимание. В некоторых случаях следует вызвать Serialize
функцию объекта, где CArchive
объект является параметром Serialize
вызова, а не с помощью << оператора >> объекта CArchive
. Важно помнить, что CArchive
>> оператор создает CObject
в памяти данные, CRuntimeClass
ранее записанные в файл архивом.
Таким образом, следует ли использовать CArchive
<< операторы и >> вызовыSerialize
, зависит от того, требуется ли архив загрузки для динамического восстановления объекта на основе ранее хранимых CRuntimeClass
сведений. Используйте функцию Serialize
в следующих случаях:
При десериализации объекта вы знаете точный класс объекта заранее.
При десериализации объекта уже выделена память.
Внимание
При загрузке объекта с помощью Serialize
функции необходимо также сохранить объект с помощью Serialize
функции. Не сохраняйте использование CArchive
<< оператора, а затем загружайте с помощью Serialize
функции или храните ее с помощью Serialize
функции, а затем загружайте с помощью CArchive >>
оператора.
В следующем примере показаны случаи:
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
}
}
В итоге, если сериализуемый класс определяет внедренный CObject
как член, то вместо этого не следует использовать CArchive
<< операторы и >> операторы для этого объекта, но следует вызывать функциюSerialize
. Кроме того, если сериализуемый класс определяет указатель на CObject
объект (или объект, производный от CObject
) в качестве члена, но создает этот другой объект в собственном конструкторе, следует также вызвать Serialize
.