_afx_inline carchive& afxapi operator>>(carchive& ar, cobject*& pob)
{ pob = ar.readobject(null); return ar; }
--->//in arcobj.cpp
cobject* carchive::readobject(const cruntimeclass* pclassrefrequested)
{
...//
// attempt to load next stream as cruntimeclass
uint nschema;
dword obtag;
cruntimeclass* pclassref = readclass(pclassrefrequested, &nschema, &obtag);//***
// check to see if tag to already loaded object
cobject* pob;
if (pclassref == null)
{
if (obtag > (dword)m_ploadarray->getupperbound())
{
// tag is too large for the number of objects read so far
afxthrowarchiveexception(carchiveexception::badindex,
m_strfilename);
}
pob = (cobject*)m_ploadarray->getat(obtag);
if (pob != null && pclassrefrequested != null &&
!pob->iskindof(pclassrefrequested))
{
// loaded an object but of the wrong class
afxthrowarchiveexception(carchiveexception::badclass,
m_strfilename);
}
}
else
{
// allocate a new object based on the class just acquired
pob = pclassref->createobject();//***
if (pob == null)
afxthrowmemoryexception();
// add to mapping array before de-serializing
checkcount();
m_ploadarray->insertat(m_nmapcount++, pob);
// serialize the object with the schema number set in the archive
uint nschemasave = m_nobjectschema;
m_nobjectschema = nschema;
pob->serialize(*this);//***
m_nobjectschema = nschemasave;
assert_valid(pob);
}
return pob;
}
--->//读取cruntimeclass信息
cruntimeclass* carchive::readclass(const cruntimeclass* pclassrefrequested,
uint* pschema, dword* pobtag)
{
...//
// make sure m_ploadarray is initialized
mapobject(null);
// read object tag - if prefixed by wbigobjecttag then dword tag follows
dword obtag;
word wtag;
*this >> wtag;//***读取标志位
if (wtag == wbigobjecttag)
*this >> obtag;
else
obtag = ((wtag & wclasstag) << 16) | (wtag & ~wclasstag);
// check for object tag (throw exception if expecting class tag)
if (!(obtag & dwbigclasstag))
{
if (pobtag == null)
afxthrowarchiveexception(carchiveexception::badindex, m_strfilename);
*pobtag = obtag;
return null;
}
cruntimeclass* pclassref;
uint nschema;
if (wtag == wnewclasstag)
{
// new object follows a new class id
if ((pclassref = cruntimeclass::load(*this, &nschema)) == null)//***
afxthrowarchiveexception(carchiveexception::badclass, m_strfilename);
// check nschema against the expected schema
if ((pclassref->m_wschema & ~versionable_schema) != nschema)
{
if (!(pclassref->m_wschema & versionable_schema))
{
// schema doesn't match and not marked as versionable_schema
afxthrowarchiveexception(carchiveexception::badschema,
m_strfilename);
}
else
{
// they differ -- store the schema for later retrieval
if (m_pschemamap == null)
m_pschemamap = new cmapptrtoptr;
assert_valid(m_pschemamap);
m_pschemamap->setat(pclassref, (void*)(dword_ptr)nschema);
}
}
checkcount();
m_ploadarray->insertat(m_nmapcount++, pclassref);
}
else
{
...//
}
// check for correct derivation
if (pclassrefrequested != null &&
!pclassref->isderivedfrom(pclassrefrequested))
{
afxthrowarchiveexception(carchiveexception::badclass, m_strfilename);
}
// store nschema for later examination
if (pschema != null)
*pschema = nschema;
else