通过存档存储和加载 CObject
要通过存档来存储和加载 CObject
,需要进行额外考量。 在某些情况下,应调用对象的 Serialize
函数,其中 CArchive
对象是 Serialize
调用的参数,而不是使用 CArchive
的 << 或 >> 运算符。 需要记住的一个要点是,CArchive
>> 运算符基于先前通过存储存档写入文件的 CRuntimeClass
信息在内存中构造 CObject
。
因此,无论是使用 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
。