网上搜索到的关于mfc类的序列化几乎都是直接派生自CObject而没有间接的,所以根据:
<c++技术内幕>第四版16.1.2节讲到,可序列化类必须直接或间接地从CObject派生而来,并且在类声明中,必须包含DECLARE_SERIAL宏,在类实现文件中必须包含IMPLEMENT_SERIAL宏.
我实现了序列化类的多态.
我的实现要求如下:
一个方形和一个圆形类都继承自图形基类.这个基类有个虚函数draw.派生类都必须能够序列化.并且利用多态进行draw.
用VC6新建单文档mfc应用程序:声明类如下:
class CMyShape :public CObject{
public :
virtual void draw(CDC* dc)=0;
CRect rect;
};
class CMyRect:public CMyShape{
public: // create from serialization only
CMyRect(){}
DECLARE_SERIAL(CMyRect)
public:
CMyRect(int left,int top,int right,int bottom){
rect.left=left;
rect.top=top;
rect.right=right;
rect.bottom=bottom;
}
void draw(CDC* dc){
dc->Rectangle(rect);
}
void Serialize(CArchive& ar){
if (ar.IsStoring())
ar<<rect;
else ar>>rect;
}
};
class CMyEllipse: public CMyShape{
public:
CMyEllipse(){}
DECLARE_SERIAL(CMyEllipse)
CMyEllipse(int left,int top,int right,int bottom){
rect.left=left;
rect.top=top;
rect.right=right;
rect.bottom=bottom;
}
void draw(CDC* dc){
dc->Ellipse(rect);
}
void Serialize(CArchive& ar){
if (ar.IsStoring())
ar<<rect;
else ar>>rect;
}
};
定义里写上:
IMPLEMENT_SERIAL(CMyRect,CObject,1)
IMPLEMENT_SERIAL(CMyEllipse,CObject,1)
在遍历对象列表进制绘制时就只用直接调用draw函数好了.中间只需要一个强制类型转换到CMyShape,因为我用的是CObList对象.
void CSerializeView::OnDraw(CDC* pDC)
{
CSerializeDoc* pDoc = GetDocument();
pDC->SelectStockObject(NULL_BRUSH);
ASSERT_VALID(pDoc);
CObList &list=pDoc->obList;
CMyShape *objP;
POSITION pos=list.GetHeadPosition();
while(pos!=NULL){
objP=(CMyShape*)list.GetNext(pos);
objP->draw(pDC);
}
// TODO: add draw code for native data here
}