mfc 序列化类(串行化类)的继承和虚函数应用

网上搜索到的关于mfc类的序列化几乎都是直接派生自CObject而没有间接的,所以根据:第四版16.1.2节讲到,可序列化类必须直接或间接地从CObject派生而来,并且在类声明中,必须包含DECLARE_SERIAL宏,在类实现文件中必须包含IMPLEMENT_SERIAL宏.我实现了序列化类的多态.我的实现要求如下:一个方形和一个圆形类都继承自图形基类.这个基类有个虚函数dra
摘要由CSDN通过智能技术生成

网上搜索到的关于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
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC序列化对象时,可以使用对象的Runtime Class(运行时)来判断型。Runtime Class是一个MFC中的,用于描述一个型信息,包括的名称、父、成员变量、成员函数等信息。每个MFC都有一个对应的Runtime Class对象,可以通过调用的GetRuntimeClass函数来获取该对象。 在序列化过程中,可以使用对象的Runtime Class来判断对象的型,例如: ``` void CMyDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // 写入数据 if (m_pShape->GetRuntimeClass() == RUNTIME_CLASS(CMyLine)) { // 如果是CMyLine对象,则写入线段相关数据 ar << (BYTE)1; // 标识为线段型 ar << (CMyLine*)m_pShape; } else if (m_pShape->GetRuntimeClass() == RUNTIME_CLASS(CMyRectangle)) { // 如果是CMyRectangle对象,则写入矩形相关数据 ar << (BYTE)2; // 标识为矩形型 ar << (CMyRectangle*)m_pShape; } // ... } else { // 读取数据 BYTE type; ar >> type; // 读取型标识 if (type == 1) { // 如果是线段型,则读取线段数据并创建CMyLine对象 m_pShape = new CMyLine; ar >> (CMyLine*)m_pShape; } else if (type == 2) { // 如果是矩形型,则读取矩形数据并创建CMyRectangle对象 m_pShape = new CMyRectangle; ar >> (CMyRectangle*)m_pShape; } // ... } } ``` 在上述代码中,通过判断对象的Runtime Class来确定对象的型,然后分别进行序列化操作。注意,在读取数据时,需要先读取型标识,然后根据标识来创建相应型的对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值