mfc只有doc才能序列化吗_MFC序列化-IMPLEMENT_SERIAL(...)

MFC源码:#define DECLARE_DYNAMIC(class_name) \public: \static const CRuntimeClass class##class_name; \virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \

public: \

static CRuntimeClass class##class_name; \

virtual CRuntimeClass* GetRuntimeClass() const; \

// not serializable, but dynamically constructable

#define DECLARE_DYNCREATE(class_name) \

DECLARE_DYNAMIC(class_name) \

static CObject* PASCAL CreateObject();

#define _DECLARE_DYNCREATE(class_name) \

_DECLARE_DYNAMIC(class_name) \

static CObject* PASCAL CreateObject();

#define DECLARE_SERIAL(class_name) \

_DECLARE_DYNCREATE(class_name) \

AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);

#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \

AFX_COMDAT const CRuntimeClass class_name::class##class_name = { \

#class_name, sizeof(class class_name), wSchema, pfnNew, \

RUNTIME_CLASS(base_class_name), NULL, class_init }; \

CRuntimeClass* class_name::GetRuntimeClass() const \

{ return RUNTIME_CLASS(class_name); }

#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \

AFX_COMDAT CRuntimeClass class_name::class##class_name = { \

#class_name, sizeof(class class_name), wSchema, pfnNew, \

RUNTIME_CLASS(base_class_name), NULL, class_init }; \

CRuntimeClass* class_name::GetRuntimeClass() const \

{ return RUNTIME_CLASS(class_name); }

#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \

IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL, NULL)

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \

CObject* PASCAL class_name::CreateObject() \

{ return new class_name; } \

IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \

class_name::CreateObject, NULL)

#define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \

CObject* PASCAL class_name::CreateObject() \

{ return new class_name; } \

extern AFX_CLASSINIT _init_##class_name; \

_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \

class_name::CreateObject, &_init_##class_name) \

AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \

CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \

{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \

return ar; }

以下是我(fyl)对这些宏的理解:

IMPLEMENT_RUNTIMECLASS中定义了静态CRuntimeClass对象,并赋予当前类与基类的信息 ,当前类类名及版本号wSchema,动态创建当前类对象的函数地址CreateObject等。

它实现了基类与派生类之间的连接,在MFC类层次之间形成了树形层次的结构,所以可以在此基础上实现动态类 型的识别IsKindOf:

while (pClassThis != NULL)

{

if (pClassThis == pBaseClass)

return TRUE;

if (pClassThis->m_pfnGetBaseClass == NULL)

return FALSE;

pClassThis = (*pClassThis->m_pfnGetBaseClass)();

}

DECLARE_DYNAMIC仅提供动态类型的识别,只需要基类与派生类之间的连接,不需要其它信息,所以IMPLEMENT_DYNAMIC调用的IMPLEMENT_RUNTIMECLASS版本号:0xFFFF(表示无效), 动态创建当前类对象的函数地址:NULL。

DECLARE_DYNCREATE增加了动态创建,所以IMPLEMENT_DYNCREATE增加了动态创建当前类对象的函数CreateObject,并传递给IMPLEMENT_RUNTIMECLASS。

DECLARE_SERIAL实现串行化(保存与读取),不同版本的保存与读取是可能存在不同的,所以需要版本号,所以IMPLEMENT_SERIAL增加了版本号传递;

另外,在读取时,读到class信息时需要判断是那个类后才可以动态生成,所以IMPLEMENT_SERIAL中增加了AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name))。

AFX_CLASSINIT是结构的定义:

struct AFX_CLASSINIT

{ AFX_CLASSINIT(CRuntimeClass* pNewClass); };

仅有一个构造函数,定义如下:

AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pNewClass)

{

pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;

CRuntimeClass::pFirstClass = pNewClass;

}

此构造函数负责 linked list 的串接工作。在MFC类中依靠AFX_CLASSINIT在原有树形的结构上增加了链表,链表将所有包含*_SERIAL对的MFC类串接后形成一个表。所以读到class信息时在此链表查询即可!

问题1(主要问题):

*_SERIAL中增加了friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);

但我没有使用它时也可以串行化!

CTrip是可串行化的类.操作如下:

头文件中用_DECLARE_DYNCREATE(CTrip)替换DECLARE_SERIAL

源文件中用CObject* PASCAL CTrip::CreateObject() \

{ return new CTrip; } \

_IMPLEMENT_RUNTIMECLASS(CTrip, CObject, 2, \

CTrip::CreateObject, NULL)\

AFX_CLASSINIT _init_CTrip(RUNTIME_CLASS(CTrip));

替换IMPLEMENT_SERIAL!

替换后CTrip同样可以完成串行化的工作?

在源文件中增加CArchive& AFXAPI operator>>(CArchive& ar, CTrip* &pOb) \

{ pOb = (CTrip*) ar.ReadObject(RUNTIME_CLASS(CTrip)); \

return ar; },并在此处设置断点,但是始终不进入,说明没有用到?

问题2:

struct CRuntimeClass

{

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值