例子
假设需要实现一个几何图形显示、编辑程序,支持可扩展的图形功能。这里不想讨论具体图形系统的实现,只讨论图像对象的保存和载入。
基类CPicture
每个图形对象都从CPicture派生,这个类实现了串行化功能,其实现代码为:
//头文件picture.h
#if !defined(__PICTURE_H__) #define __PICTURE_H__
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
const int TYPE_UNKNOWN = -1; class CPicture:public CObject { int m_nType;//图形类别 DECLARE_SERIAL(CPicture) public: CPicture(int m_nType=TYPE_UNKNOWN):m_nType(m_nType){}; int GetType()const {return m_nType;}; virtual void Draw(CDC * pDC); void Serialize(CArchive & ar); }; #endif
//cpp文件picture.cpp #include "stdafx.h" #include "picture.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
void CPicture::Draw(CDC * pDC) { //基类不实现绘图功能,由派生类实现 }
void CPicture::Serialize(CArchive & ar) { if(ar.IsLoading()) { ar << m_nType; }else{ ar >> m_nType;
} } |
注意:由于CRuntimeClass要求这个对象必须能够被实例化,因此虽然Draw函数没有任何绘图操作,这个类还是没有把它定义成纯虚函数。
对象在CDocument派生类中的保存和文件I/O过程
为了简化设计,在CDocument类派生类中,采用MFC提供的模板类CPtrList来保存对象。该对象定义为:
protected: CTypedPtrList m_listPictures;
由于CTypedPtrList和CPtrList都没有实现Serialize函数,因此不能够通过ar << m_listPictures和ar >> m_listPictures 来序列化对象,因此CPictureDoc的Serialize函数需要如下实现:
void CTsDoc::Serialize(CArchive& ar) { POSITION pos; if (ar.IsStoring()) { // TODO: add storing code here pos = m_listPictures.GetHeadPosition(); while(pos != NULL) { ar << m_listPictures.GetNext (pos); } } else { // TODO: add loading code here RemoveAll(); CPicture * pPicture; do{ try { ar >> pPicture; TRACE("Read Object %d\n",pPicture->GetType ()); m_listPictures.AddTail(pPicture); } catch(CException * e) { e->Delete (); break; } }while(pPicture != NULL); } m_pCurrent = NULL; SetModifiedFlag(FALSE); } |
实现派生类的串行化功能
几何图形程序支持直线、矩形、三角形、椭圆等图形,分别以类CLine、CRectangle、CTriangle和CEllipse实现。以类CLine为例,实现串行化功能:
从CPicture派生CLine,在CLine类定义中增加如下成员变量: CPoint m_ptStart,m_ptEnd;
在该行下一行增加如下宏: DECLARE_SERIAL(CLine)
实现Serialize函数
void CLine::Serialize(CArchive & ar) { CPicture::Serialize(ar); if(ar.IsLoading()) { ar>>m_ptStart.x>>m_ptStart.y>>m_ptEnd.x>>m_ptEnd.y; }else{ ar<<m_ptStart.x<<m_ptStart.y<<m_ptEnd.x<<m_ptEnd.y; } } |
在CPP文件中增加 IMPLEMENT_SERIAL(CLine,CPicture,TYPE_LINE);
这样定义的CLine就具有串行化功能,其他图形类可以类似定义。
|