您的位置:首页 > 其它

串形化与动态创建(Serilize & DynamicCreate)

2011-01-14 08:43 162 查看
串形化与动态创建(Serilize & DynamicCreate)
问题的来源
当知道一个类的名称,比如是“CNode”怎样创建它的对象呢?你可能会用以下的方式:
CString className;
//从文件或屏幕上读取类名到className中
CObject* p = new className;
那就大错特错了,
没有一个c++编译器支持语言版的动态创建!

动态创建
看看MFC动态创建思路吧。
为了使用类型兼容原则,要创建的类必须派生自CObject(这是MFC“黑幕”的基础)。当一个类声明了DECLARE_SERIAL,并实现IMPLEMENT_SERIAL
两个宏以后,这个类就拥有一个自己的“名片”——静态成员CRuntimeClass(与CObject一样在MFC中几乎无处不在)。并会自动把自己的“名片”加个一由一串CRuntimeClass组成的“类别型录网”(这名字有点怪,引用侯捷的叫法)。这个“名片”拥有两个重要成员即类名与该类的创建函数。于是只要知道该类的类名就可以在这个“类别型录网”中找到这个类的创建函数了。因为这静态的所以这个名片属于类,下文对象的“片名”就是指类的“片名”。
动态创建在对象串形化(对象的文件读写,由CArchive负责)中可谓是大显神威!

串形化

一、对象写过程,相对简单,没有用到动态创建:
1.
写对象“名片”。想想不写“名片”到时候挖出来,谁认识呀!
2.
写对象数据。这是在做“有用功”的时候,是用户自己说的算了。
写过程相关事宜:
为了提高效率,CArchive还在写“名片”时候,做了一些小动作,大概意思是:如果一个类的
“片名”已经登记过了,那就没有必要再写一次“名片”了,只是做一个已登记标识。
写名片到底写了什么?
名片里有类名,也有创建函数,都可以写进去吗?不,创建函数在每次加载程序的时候,那个巨大的“类别型录网”会重建,创建函数的地址当然不能确保不变。所以现在创建函数没有参考价值的。只能写一个名字。到时候等“类别型录网”重建完,创建函数安家落户了,我们再用名字去找它。
这个两写动作到底怎么写?
写“片名”是由CRuntimeClass说了算,写对象数据就由对象说了算,类是程序员定义的,就是说程序员说了算。CArchive只是在中间提供组织管理作用用,具体写什么,还是调用CRuntimeClass与类的相关函数完成的。由于CRuntimeClass是MFC做死固化了的,所以程序员当然管不了了,也没有必要管,因为它做的不是
“有用功”。真正做“有用功”的写对象数据,这里你想怎么写都行。

二、对象读过程,该拿出动态创建的时候了。
写过程告诉我们应该先读对象
“片名”,再读取存入的对象数据。写“片名”过程上面已经交代,读“名片”只能获得类名这唯一有用线索。现在这拿着类名,找到“类别型录网”的入口,遍历这个“网”,看看哪个“片名”的类名与现在拿着的类名相同,相同就找到了,用这个“名片”的创建函数,创建一个类对象吧!大功告成!
有那这个类对象,我们才可以读对象数据。因为读对象函数(serialize)要用这个对象调用,这是为什么要创建类对象的原因。
细节问题:(恐怕只有源码才能说清楚):
CArchive为提高效率的方法,使用的标识
“类别型录网”的创建,与入口的查找
补充内容:
使用一个类具有“串形化能力(serializable)”意思就是:可以有太磁盘文件中创建它。
这样的类应该具备的条件:
1.
从CObject派生。为使用类型兼容原则,是多态的前提。
2.
添加了DECLARE_SERIAL
IMPLEMENT_SERIAL两个宏。为自己打造一个“片名”加入“类别型录网”。
3.
有一个无参构造函数。创建对象时用的。
4.
有一个serialize函数。让MFC调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: