MFC技术内幕系列之(五)---MFC文档序列化内幕[4]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 bigwhite20xx 的 blog

     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

本文关键:文档序列化
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top