对于核心数据相对比较集中的应用程序来说,serialization机制可以直接充当文档保存与打开功能的实现工具,这也是很多成熟的应用程序framework都提供serialization支持的原因
但是个人认为,serialization最精彩的用处在于保存现场,比如在探索性的科研应用程序开发过程中,很可能一部分算法已经固定下来,其余的有待进一步探索,而确定下来的部分有可能十分time consuming,如果每次改一下算法都要从头计算,就会很费时间,长期下去对工作情绪会有很大影响,这时候可以用serialization把每一步的结果存成文件,下次启动时任选一个开始新的计算。
		Boost的Serialization库是一个十分强大的工具,它文档中提到的11个开发目标列举如下:
1.代码移植性,只依赖于ANSI C++标准
2.代码简洁性,的确运用Boost::Serialization所需要的代码量很小
3.每个类有自己独立的版本控制,以保证旧的save结果可以被新的程序load回来
4.深度指针save与load,不仅serialize指针本身,而且包括它指向的对象数据
5.多个指针指向同一个对象不会被serialize多次
6.对常用STL容器的支持
7.串行数据的平台移植性
8.类如何被串行化与串行数据按何种格式存储相互无关
9.非侵入性,这对于数据中使用了第三方类库的情形很有效
		最后两个没有理解,希望高人指点
10.The archive interface must be simple enough to easily permit creation of a new type of archive. 
11.The archive interface must be rich enough to permit the creation of an archive that presents serialized data as XML in a useful manner.
下面是我试用Boost::Serialization的记录
		第一个例子
		假设有这样一个类需要串行化
		 
		
				 class
				 Data
				class
				 Data

 
				
						 {
				
				
						{
 public
						:
						public
						:
 int
						 mInt;
    
						int
						 mInt;
 }
				
				;
}
				
				;
		 
		 
		这里为了简化起见,成员变量都设成public了,串行化的代码如下
		 
		
				 1
				 #include 
				<
				fstream
				>
				#include 
				<
				fstream
				>
				
						
				
				 2
				
						 
						
				
				 3
				
						 //
				 fewest include headers
				
				//
				 fewest include headers
				
						
				
				 4
				
						 #include 
				<
				boost
				/
				archive
				/
				text_iarchive.hpp
				>
				
				#include 
				<
				boost
				/
				archive
				/
				text_iarchive.hpp
				>
				
						
				
				 5
				
						 #include 
				<
				boost
				/
				archive
				/
				text_oarchive.hpp
				>
#include 
				<
				boost
				/
				archive
				/
				text_oarchive.hpp
				>
				
						
				
				 6
				
						 
						
				
				 7
				
						 //
				 use this to ease the archive selection
				
				//
				 use this to ease the archive selection
				
						
				
				 8
				
						 typedef boost::archive::text_iarchive iarchive;
				
				typedef boost::archive::text_iarchive iarchive;
				 9
				
						 typedef boost::archive::text_oarchive oarchive;
typedef boost::archive::text_oarchive oarchive;
				10
				
						 
						
				
				11
				
						 class
				 Data
				
				class
				 Data
				12
				
						 
						 
				
				
						 {
				
				
						{
						13
						
								 friend 
						class
						 boost::serialization::access;
    friend 
						class
						 boost::serialization::access;
						14
						
								 
								
						
						15
						
								 protected
						:
						
						protected
						:
						16
						
								 
								
						
						17
						
								 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
						
						18
						
								 
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
						19
						
								 
								 
    
						
								 {
						
						
								{
								20
								
										 ar 
								&
								 mInt;
        ar 
								&
								 mInt;
								21
								
										 }
    }
						
						
								
						
						22
						
								 
								
						
						23
						
								 public
						:
						
						public
						:
						24
						
								 
								
						
						25
						
								 int
						 mInt;
    
						int
						 mInt;
						26
						
								 
								
						
						27
						
								 static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName)
    
						static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName)
						28
						
								 
								 
    
						
								 {
						
						
								{
								29
								
										 std::ofstream ofs(fileName.c_str());
        std::ofstream ofs(fileName.c_str());
								30
								
										 oarchive oa(ofs);
        oarchive oa(ofs);
								31
								
										 oa 
								<<
								 obj;
        oa 
								<<
								 obj;
								32
								
										 }
    }
						
						
								
						
						33
						
								 
								
						
						34
						
								 static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName)
    
						static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName)
						35
						
								 
								 
    
						
								 {
						
						
								{
								36
								
										 std::ifstream ifs(fileName.c_str());
        std::ifstream ifs(fileName.c_str());
								37
								
										 iarchive ia(ifs);
        iarchive ia(ifs);
								38
								
										 ia 
								>>
								 obj;
        ia 
								>>
								 obj;
								39
								
										 }
    }
						
						
								
						
						40
						
								 }
				
				;
}
				
				;
				41
				
						 
						
				
				42
				
						 void
				 main()
				
				void
				 main()
				43
				
						 
						 
				
				
						 {
				
				
						{
						44
						
								 Data d1;
    Data d1;
						45
						
								 d1.mInt 
						=
						 
						3
						;
    d1.mInt 
						=
						 
						3
						;
						46
						
								 
								
						
						47
						
								 Data::saveData(d1, 
						"
						output.txt
						"
						);
    Data::saveData(d1, 
						"
						output.txt
						"
						);
						48
						
								 
								
						
						49
						
								 Data d2;
    Data d2;
						50
						
								 Data::loadData(d2, 
						"
						output.txt
						"
						);
    Data::loadData(d2, 
						"
						output.txt
						"
						);
						51
						
								 
								
						
						52
						
								 //
						 results should be the same.
    
						//
						 results should be the same.
						
								
						
						53
						
								 ToolLib::LOG(TOSTR(d2.mInt));
						
						    ToolLib::LOG(TOSTR(d2.mInt));
						54
						
								 }
}
				
		 
		 
		成员serialize函数是定义类如何被串行化之规则的核心。
由于使用了RTTI机制,serialize函数不需要为virtual,永远只要是void就可以,在串行化指针的时候能够被正确调用。
serialize函数中的 & 运算符在load时调用 >>,而在save时调用 <<,这样save和load只要一个函数就可以。
saveData和loadData函数必不可少,由于serialization库强大的编译检查机制,如果不用这样的方式来save一个对象,往往会因为这个对象不是const而编译失败。
所用的archive类型可以任选,如text或binary,上例中的typedef即是为了封装这一变化
		非侵入性
		下面一例演示了串行化不可侵入的类型。这里用的是 WildMagicLib2.5中的 2-Vector
		 
		
				 #include 
				<
				WildMagic2p5
				/
				Include
				/
				WmlVector2.h
				>
				#include 
				<
				WildMagic2p5
				/
				Include
				/
				WmlVector2.h
				>
				
						
						 
						
						 class
				 Data
				
				class
				 Data

 
				
						 {
				
				
						{
 friend 
						class
						 boost::serialization::access;
    friend 
						class
						 boost::serialization::access;

 protected
						:
						protected
						:

 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)

 
    
						
								 {
						
						
								{
 ar 
								&
								 mVec2d;
        ar 
								&
								 mVec2d;
 }
    }
						
						
								
								 
								
								 public
						:
						
						public
						:

 Wml::Vector2d mVec2d;
    Wml::Vector2d mVec2d;

 static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName);
    
						static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName);
 static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName);
    
						static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName);
 }
				
				;
}
				
				;


 namespace
				 boost
				namespace
				 boost 
				
						 {
				
				
						{ 

 namespace
						 serialization
						namespace
						 serialization 
						
								 {
						
						
								{
 template
								<
								class
								 Archive, 
								class
								 Real
								>
    template
								<
								class
								 Archive, 
								class
								 Real
								>
								
										
										 void
								 serialize(Archive
								&
								 ar, Wml::Vector2
								<
								Real
								>&
								 g, 
								const
								 unsigned 
								int
								 version)
    
								void
								 serialize(Archive
								&
								 ar, Wml::Vector2
								<
								Real
								>&
								 g, 
								const
								 unsigned 
								int
								 version)

 
    
								
										 {
								
								
										{
 ar 
										&
										 g.X();
        ar 
										&
										 g.X();
 ar 
										&
										 g.Y();
        ar 
										&
										 g.Y();
 }
    }
								
								
										
										 }
						
						 
						//
						 namespace serialization
}
						
						 
						//
						 namespace serialization
						
								
								 }
				
				 
				//
				 namespace boost
						
						}
				
				 
				//
				 namespace boost
 
		 
		 
		这种情况下,需要这个全局serialize在能够访问到那个类里需要串行化的数据,常常load和save的方法不一样,如load时调用setVar,save时调用getVar,这时Archive::is_loading和Archive::is_saving常数就有用了。一种等价但是更直观的方法是使用BOOST_SERIALIZATION_SPLIT_MEMBER或者BOOST_SERIALIZATION_SPLIT_FREE宏,两者分别生成调用load/save成员函数和load/save全局函数的代码。
		在serialization内部,是通过定义全局serialize函数模板,并在里面调用成员serialize函数来实现的,如下所示,需要非侵入的对象只要特化这个全局函数就可以了。
		 
		
				 //
				 default implemenation - call the member function "serialize"
				//
				 default implemenation - call the member function "serialize"
				
						
						 template
				<
				class
				 Archive, 
				class
				 T
				>
				
				template
				<
				class
				 Archive, 
				class
				 T
				>
				
						
						 inline 
				void
				 serialize(
inline 
				void
				 serialize(
 Archive 
				&
				 ar, T 
				&
				 t, 
				const
				 BOOST_PFTO unsigned 
				int
				 file_version
    Archive 
				&
				 ar, T 
				&
				 t, 
				const
				 BOOST_PFTO unsigned 
				int
				 file_version

 )
)
				
						 {
				
				
						{
 access::serialize(ar, t, static_cast
						<
						unsigned 
						int
						>
						(file_version));
    access::serialize(ar, t, static_cast
						<
						unsigned 
						int
						>
						(file_version));
 }
}
				
		 
		 
		STL容器支持
		通过包含一些serialization提供的头文件,对STL容器可以像普通变量一样支持
		 
		
				 //
				 STL support headers
				//
				 STL support headers
				
						
						 #include 
				<
				boost
				/
				serialization
				/
				vector.hpp
				>
				
				#include 
				<
				boost
				/
				serialization
				/
				vector.hpp
				>
				
						
						 #include 
				<
				boost
				/
				serialization
				/
				string
				.hpp
				>
#include 
				<
				boost
				/
				serialization
				/
				string
				.hpp
				>
				
						
						 
						
						 class
				 Data
				
				class
				 Data

 
				
						 {
				
				
						{
 friend 
						class
						 boost::serialization::access;
    friend 
						class
						 boost::serialization::access;

 protected
						:
						protected
						:

 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)

 
    
						
								 {
						
						
								{
 ar 
								&
								 mStr;
        ar 
								&
								 mStr;
 ar 
								&
								 mVecInt;
        ar 
								&
								 mVecInt;
 ar 
								&
								 mVecStr;
        ar 
								&
								 mVecStr;
 }
    }
						
						
								
								 
								
								 public
						:
						
						public
						:

 std::
						string
						 mStr;
    std::
						string
						 mStr;
 std::vector
						<
						int
						>
						 mVecInt;
    std::vector
						<
						int
						>
						 mVecInt;
 std::vector
						<
						std::
						string
						>
						 mVecStr;
    std::vector
						<
						std::
						string
						>
						 mVecStr;

 static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName);
    
						static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName);
 static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName);
    
						static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName);
 }
				
				;
}
				
				;
		 
		 
		指针与数组
		 
		
				 class
				 ClassA
				class
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:
 int
						 mInt;
    
						int
						 mInt;
 }
				
				;
}
				
				;

 class
				 Data
				class
				 Data

 
				
						 {
				
				
						{
 friend 
						class
						 boost::serialization::access;
    friend 
						class
						 boost::serialization::access;

 protected
						:
						protected
						:

 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)

 
    
						
								 {
						
						
								{
 ar 
								&
								 mPtrInt;
        ar 
								&
								 mPtrInt;
 ar 
								&
								 mArrInt;
        ar 
								&
								 mArrInt;
 ar 
								&
								 mPtrData;
        ar 
								&
								 mPtrData;
 ar 
								&
								 mPtrA;
        ar 
								&
								 mPtrA;
 }
    }
						
						
								
								 
								
								 public
						:
						
						public
						:


 Data():mPtrData(NULL), mPtrInt(NULL), mPtrA(NULL)
    Data():mPtrData(NULL), mPtrInt(NULL), mPtrA(NULL)
						
								 {}
						
						
								{}
						
						
								
								 
								
								 Data
						*
						 mPtrData;
    Data
						*
						 mPtrData;
 int
						 mArrInt[
						10
						];
    
						int
						 mArrInt[
						10
						];
 int
						*
						 mPtrInt;
    
						int
						*
						 mPtrInt;
 ClassA
						*
						 mPtrA;
    ClassA
						*
						 mPtrA;

 static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName);
    
						static
						 
						void
						 saveData(
						const
						 Data
						&
						 obj, std::
						string
						 fileName);
 static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName);
    
						static
						 
						void
						 loadData(Data
						&
						 obj, std::
						string
						 fileName);
 }
				
				;
}
				
				;


 namespace
				 boost
				namespace
				 boost 
				
						 {
				
				
						{ 

 namespace
						 serialization
						namespace
						 serialization 
						
								 {
						
						
								{
 template
								<
								class
								 Archive
								>
    template
								<
								class
								 Archive
								>
								
										
										 void
								 serialize(Archive
								&
								 ar, 
								int
								&
								 g, 
								const
								 unsigned 
								int
								 version)
    
								void
								 serialize(Archive
								&
								 ar, 
								int
								&
								 g, 
								const
								 unsigned 
								int
								 version)

 
    
								
										 {
								
								
										{
 ar 
										&
										 g;
        ar 
										&
										 g;
 }
    }
								
								
										
										 }
						
						 
						//
						 namespace serialization
}
						
						 
						//
						 namespace serialization
						
								
								 }
				
				 
				//
				 namespace boost
						
						}
				
				 
				//
				 namespace boost
 
		 
		 
		数组可以直接串行化,指针比须保证有效,所以必须保证在串行化之前经过初始化。
对于基本类型如int,可以直接串行化,但其指针int*,要当作不可侵入类型的指针来看待,所以需要一个全局serialize函数来说明int类型的串行化方式
		对于有基类指针的串行化,代码如下
		 
		
				 class
				 ClassA
				class
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:
 int
						 mIntA;
    
						int
						 mIntA;

 virtual
						 
						void
						 someMethod() 
						=
						 NULL;
    
						virtual
						 
						void
						 someMethod() 
						=
						 NULL;
 
    
 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)

 
    
						
								 {
						
						
								{
 ar 
								&
								 mIntB;
        ar 
								&
								 mIntB;
 }
    }
						
						
								
								 }
				
				;
}
				
				;

 BOOST_IS_ABSTRACT(ClassA)
BOOST_IS_ABSTRACT(ClassA)

 class
				 ClassB: 
				public
				 ClassA
				class
				 ClassB: 
				public
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:
 int
						 mIntB;
    
						int
						 mIntB;
 
    

 virtual
						 
						void
						 someMethod()
    
						virtual
						 
						void
						 someMethod()
						
								 {}
						
						
								{}
						
						
								
								 
								
								 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 
						/**/
						
								/*
								 file_version 
								*/
						
						)

 
    
						
								 {
						
						
								{
 ar 
								&
								 boost::serialization::base_object
								<
								ClassA
								>
								(
								*
								this
								);
        ar 
								&
								 boost::serialization::base_object
								<
								ClassA
								>
								(
								*
								this
								);
 ar 
								&
								 mIntB;
        ar 
								&
								 mIntB;
 }
    }
						
						
								
								 }
				
				;
}
				
				;

 BOOST_CLASS_EXPORT(ClassB)
BOOST_CLASS_EXPORT(ClassB)
		 
		 
		纯虚类后加上BOOST_ISABSTRACT,而可能会被串行化到的子类用BOOST_CLASS_EXPORT,这样就可以在任何地方串行化 ClassA* 的成员变量。
子类的serialize函数里必须要照顾到基类的成员。
		版本控制
		在serialize函数中的version参数就是用于版本控制的,所有类的版本号默认为0,新版本的类可以自己指定版本号以便与旧版本相区别。如下
		BOOST_CLASS_VERSION(ClassA, 1)
		对于save过程,版本号始终为新的,而load过程取决于文件中保存的值,对于新版本新增变量的情况可以这样解决
		 
		
				 //
				 old definition
				//
				 old definition
				
						
						 class
				 ClassA
				
				class
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:
 int
						 mInt;
    
						int
						 mInt;
 }
				
				;
}
				
				;

 //
				 new definition
				//
				 new definition
				
						
						 class
				 ClassA
				
				class
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:
 int
						 mInt;
    
						int
						 mInt;
 int
						 mIntNew;
    
						int
						 mIntNew;

 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 ver)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 ver)

 
    
						
								 {
						
						
								{
 ar 
								&
								 mInt;
        ar 
								&
								 mInt;

 if
								(ver 
								==
								 
								1
								)
        
								if
								(ver 
								==
								 
								1
								)
 ar 
								&
								 mIntB;
            ar 
								&
								 mIntB;
 }
    }
						
						
								
								 }
				
				;
}
				
				;

 BOOST_CLASS_VERSION(ClassA, 
				1
				)
BOOST_CLASS_VERSION(ClassA, 
				1
				)
		 
		 
		对于有改动的情形,稍微复杂一点,可以这样
		 
		
				 //
				 old definition
				//
				 old definition
				
						
						 class
				 ClassA
				
				class
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:
 TypeA mVarA;
    TypeA mVarA;
 }
				
				;
}
				
				;

 //
				 new definition
				//
				 new definition
				
						
						 class
				 ClassA
				
				class
				 ClassA

 
				
						 {
				
				
						{
 public
						:
						public
						:

 //
						 suppose now we use B and C instead of A
    
						//
						 suppose now we use B and C instead of A
						
								
								 TypeB mVarB;
						
						    TypeB mVarB;
 TypeC mVarC;
    TypeC mVarC;

 template
						<
						class
						 Archive
						>
    template
						<
						class
						 Archive
						>
						
								
								 void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 ver)
    
						void
						 serialize(Archive 
						&
						 ar, 
						const
						 unsigned 
						int
						 ver)

 
    
						
								 {
						
						
								{
 if
								(ver 
								<
								 
								1
								)
        
								if
								(ver 
								<
								 
								1
								)

 
        
								
										 {
								
								
										{
 //
										 here must be loading
            
										//
										 here must be loading
										
												
												 
										
										
												
												 TypeA varA;
            TypeA varA;
 ar 
										&
										 varA;
            ar 
										&
										 varA;
 
            
 //
										 now derive mVarB & mVarC from varA;
            
										//
										 now derive mVarB & mVarC from varA;
										
												
												 }
										
										        }
								
								
										
										 else
        
								else
								
										
										 
										 
        
								
										 {
								
								
										{
 ar 
										&
										 mVarB;
            ar 
										&
										 mVarB;
 ar 
										&
										 mVarC;
            ar 
										&
										 mVarC;
 }
        }
								
								
										
										 }
    }
						
						
								
								 }
				
				;
}
				
				;

 BOOST_CLASS_VERSION(ClassA, 
				1
				)
BOOST_CLASS_VERSION(ClassA, 
				1
				)
