WEB开发网
开发学院软件开发VC FMD开发文集 -- CArchive原理 阅读

FMD开发文集 -- CArchive原理

 2010-03-28 20:34:54 来源:WEB开发网   
核心提示:七.CObject派生对象的读写MFC中多数类都从CObject类派生,CObject类与CArchive类有着良好的合作关系,FMD开发文集 -- CArchive原理(5),能实现将对象序列化储存到文件或其他媒介中去,或者读取预先储存的对象,//将对象写入到缓冲区void CArchive::WriteObject

七.CObject派生对象的读写

MFC中多数类都从CObject类派生,CObject类与CArchive类有着良好的合作关系,能实现将对象序列化储存到文件或其他媒介中去,或者读取预先储存的对象,动态建立对象等功能。

①CObject定义了针对CArvhive的输入输出操作符,可以向其他基本数据类型一样使用"<<"、"<<"符号

CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb)
  { ar.WriteObject(pOb); return ar; }
CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb)
  { pOb = ar.ReadObject(NULL); return ar; }
当使用这些符号时,实际上执行的是CArchive的WriteObject和ReadObject成员

②WriteObject与ReadObject

在WriteObject与ReadObject中先写入或读取运行时类信息(CRuntimeClas),再调用Serialze(..),按其中的代码读写具体的对象数据。

因此,只要在CObject派生类中重载Serilize()函数,写入具体的读写过程,就可以使对象具有存储与创建能力。

//将对象写入到缓冲区
void CArchive::WriteObject(const CObject* pOb)
{
  DWORD nObIndex;
  // 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)(*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*)m_nMapCount++;
    // 调用CObject的Serialize成员,按其中的代码写入类中数据。
    ((CObject*)pOb)-> Serialize(*this);
  }
}
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
  {
    // 建立对象
    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); //调用CObject的Serialize,按其中代码读入对象数据。
    m_nObjectSchema = nSchemaSave;
    ASSERT_VALID(pOb);
  }
  return pOb;
}

上一页  1 2 3 4 5 6  下一页

Tags:FMD 开发 文集

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接