if (ar.isstoring())
{
// todo:在此添加存储代码/写入
ar<<(word)m_npenwidth;
m_pointarray.serialize(ar);
}
else
{
// todo:在此添加加载代码/读出
word w;
ar>>w;
m_npenwidth=w;
m_pointarray.serialize(ar);
}
下面我们可以继续我们的挖掘了:
ctypedptrlist::serialize函数被调用,由于ctypedptrlist并为改写serialize函数,所以实际调用的是其基类coblist的serialize函数;
//in list_o.cpp
void coblist::serialize(carchive& ar)
{
assert_valid(this);
cobject::serialize(ar);
if (ar.isstoring())
{
ar.writecount(m_ncount);//***
for (cnode* pnode = m_pnodehead; pnode != null; pnode = pnode->pnext)
{
assert(afxisvalidaddress(pnode, sizeof(cnode)));
ar << pnode->data;//***
}
}
else
{
...//
}
}
其中void carchive::writecount(dword_ptr dwcount)函数用于将coblist中的表元素个书写入。
carchive重载了<<运算符,代码如下:
//in afx.inl
_afx_inline carchive& afxapi operator<<(carchive& ar, const cobject* pob)
{ ar.writeobject(pob); return ar; }
//in arcobj.cpp
void carchive::writeobject(const cobject* pob)
{
...//
// make sure m_pstoremap is initialized
mapobject(null);
if (pob == null)
{
// save out null tag to represent null pointer
*this << wnulltag;
}
else if ((nobindex = (dword)(dword_ptr)(*m_pstoremap)[(void*)pob]) != 0)
// assumes initialized to 0 map
{
// save out index of already stored object
if (nobindex < wbigobjecttag)
*this << (word)nobindex;
else
{
*this << wbigobjecttag;
*this << nobindex;
}
}
else
{
// write class of object first
cruntimeclass* pclassref = pob->getruntimeclass();
writeclass(pclassref);//***
// enter in stored object table, checking for overflow
checkcount();
(*m_pstoremap)[(void*)pob] = (void*)(dword_ptr)m_nmapcount++;
// cause the object to serialize itself
((cobject*)pob)->serialize(*this);//***
}
}
((cobject*)pob)->serialize(*this);
循线而上,你可以发现该函数最终调用的是cstroke::serialize(carchive&ar);
也许你可能不晓得wnulltag,dwbigclasstag等之类是何东东?看看下面它们是如何定义的:
// pointer mapping constants,in arcobj.cpp
#define wnulltag ((word)0) // special tag indicating null ptrs
#define wnewclasstag ((word)0xffff) // special tag indicating new cruntimeclass
#define wclasstag ((word)0x8000) // 0x8000 indicates class tag (or'd)
#define dwbigclasstag ((dword)0x80000000) // 0x8000000 indicates big class tag (or'd)
#define wbigobjecttag ((word)0x7fff) // 0x7fff indicates dword object tag
#define nmaxmapcount ((dword)0x3ffffffe) // 0x3ffffffe last valid mapcount
他们不是别的,只是一些记号,比如当你写入一个cstroke类时,它首先判断cstroke以前是否出现过,若没有,则写入 wnewclasstag (0xffff),否则写入wclasstag+一定的offsets,表示这是与前面相同的旧类。
//mfc文档:to store the version and class information of a base class during serialization of the derived class.
void carchive::writeclass(const cruntimeclass* pclassref)
{
...//
// make sure m_pstoremap is initialized
mapobject(null);
// write out class id of pob, with high bit set to indicate
// new object follows
// assume: initialized to 0 map