序列化:利用C++模板编写的序列化框架



介绍

  在这个框架中包含了个序列化基本框架套基本类型识别系统可以识别基础类型复杂类型自定义类型std容器类型而且可以这个基础上进行递归扩展

  可以将复杂数据结构序列化到文件并从文件中恢复

  包含了完整自动单元测试和测试案例点此下载

  正文

  写这个序列化框架最初是想用在个大型项目上在那个项目中有些相当复杂在运行时构建出来树形数据结构如果可以将这个内存树序列化起来可以大大节约下次创建时间另外在自己做些小工具中有些数据想保存在文件中以后再从文件中读取用序列化方式也十分方便而且那时正好系统学习了下c模板技术感觉在编程活动中很难用到些比较高级模板技术所以想用c模板技术来写这个序列化框架最后那个项目中没有使用这个序列化框架但我至少达到了第 2个目标写这个序列化框架让我对c模板技术有了更深层次理解

  在这个框架中包含了个序列化基本框架套基本类型识别系统可以识别基础类型复杂类型自定义类型std容器类型而且可以这个基础上进行递归扩展

  在写这个框架同时我也写了完整测试案例如果没有测试案例要调试这样框架可就真是难和登天模板方面编译器报出来信息很难看根本就没用

  代码是在vc7.1下写也只能在vc7.1下用vc6对于c模板支持非常有限而其他编译器在这方面支持也有出入如果要用于其他编译器可能要修改部分类型识别方面代码测试框架我用是cppunit(1.9.14)这是个开源测试框架可以在www.xprogramming.com下载到其中类型识别方面代码我主要是参考了c template和boost中部分代码

  由于是用模板写比mfc中运行时序列化框架在效率上表现要好得多使用起来也相当简单如果要学习c模板高级技术研究下这个框架可以获益良多由于是框架代码我写得相当规范标准有注释也有完整测试案例可以进行自动回归测试

  使用思路方法比较简单请参考(filerwtest.cpp)文件中测试案例

  普通数据类型:

(unsigned char, unsigned , unsigned , unsigned long, signed char, signed , signed , signed long, bool, char, wchar_t, unsigned long long, signed long long, float, double, long double)可以直接序列化及反序列化

  对于指针类型:

  会序列化指针具体指向对象如果指针指向对象类型是序列化框架无法识别类型会报出编译注意在反序列化时只需要传个空指针即可序列化框架会将被序列化对象值反序列化到堆上并将地址付给指针如果传个有值指针在debug模式下会在运行时引发个断言在release下会导致原来指针指向对象被泄漏

\" width=603 usemap=#map border=0 _disibledevent=>500)this.style.width=500;\" _disibledevent=>
  对于普通数据类型:

  会将整个以内存拷贝方式序列化到内存即使没被真正赋值元素反序列化时传个相同类型即可需要注意传进容量必须大于或等于被序列化容量否则会引发越界内存在debug模式下会引发个断言

  非普通数据类型:

  元素类型可以是除普通数据类型的外所有被序列化框架所支持类型序列化时会针对每个元素序列化框架对它具体序列化特化反序列化时亦然由于在release模式下类类型在申明后编译器会生成相应类缺省构造代码但对于原始类型如指针类型如果不显式手工值是无意随机值这种情况序列化框架无法识别会赞成严重内存另对于指针某些元素为null情况序列化框架也无法处理在debug模式下会引发个断言

  因些如果是指针除非元素全部为有意义指针否则不应该做为来序列化而应该加入相应遍历逻辑将有意思元素逐个序列化

  对于如果有意思只是其中少部分元素也应该以上述方式进行序列化以提高性能

  自定义数据类类型:

  不需要拷贝构造不需要拷贝赋值不需要析构如老式struct结构类型这种类型可以通过直接拷贝内存而被高效序列化及化序列化只需要让个类从_data__tag派生序列化框架就会将它当成普通数据类类型处理

  自定义复杂类型:

  对于非数据类类型必须从cserializable派生关在类定义中加入serializable(name, x)宏name是该类名字x是相应版本号版本号引入主要是避免在个类被修改后和以前生成序列化文件起使用以免引起内存在类中还必须实现virtual bool serialize(cmedia *) const;在该中写具体序列化代码内容很简单按序列化及反序列化用为两段简单为每个需要序列化及反序列化成员即可如下列:

(pmedia->isstoring) {
 *pmedia << m_1 << m_2 << m_3 << m_4 << m_5;
  true;
}
(pmedia->isloading) {
 *pmedia >> m_1 >> m_2 >> m_3 >> m_4 >> m_5;
  true;
}
  注意序列化和反序列化顺序这要错

  std::及std::w类型:

  使用比较简单值得注意是和将指针用情况如果申明了个容量很大(般是为了避免在追加时内存重分配开销)却只用了小部分序列化并反序列化对象容量只是刚好有内存那部分

  std::pair类型:

  只要是pairfirst和second必须是序列化框架所支持类型就可以被正常序列化及反序列化

  std容器类型:

(vector,list,deque,stack,queue,,multi,map,multimap)



  支持以上容器类型其中容器中元素类型必须是序列化框架所支持类型
Tags:  序列化框架 java序列化 序列化

延伸阅读

最新评论

发表评论