原文翻译自:http://uscilab.github.io/cereal/serialization_functions.html#minimal
Serialization函数
由于C++缺少反射机制(即程序运行时加载未知class),所以实现serialization时需要指明那些数据需要序列化或反序列化。庆幸的是,Cereal提供了多种序列化函数完成上述指定工作。
TLDR版本
Cereal支持单独使用serialization函数,或者分别使用load/save函数来进行序列化。load函数和save函数也可以被设计成load_minimal函数和save_minimal函数(详情见下文)。
当把serialization函数放在class外部时,你可以将其设置为class的私有方法,当然你必须将其声明为class的友元函数,方法是添加cereal::access,具体细节见下文。
关于存储Cereal版本信息的问题,之前的博客已经提到过,可以通过声明宏CEREAL_CLASS_VERSION和给serialization函数添加一个std::uint32_t const version的参数来解决。
各式各样的Serialization函数
serialization可以任意放置在class的内外,也可以随意选择单独的serialization function或者分开的load/save function。
如果没有特殊情况,推荐使用serialization function,更加方便。和Boost不一样的时,当你选定某种Serialization函数时,你并不需要使用宏来告诉编译器你具体使用了哪一种。Cereal会自动识别你究竟使用了serialization function还是load/save function。
内部serialization function
struct MyClass
{
int x, y, z;
template<class Archive>
void serialize(Archive & archive)
{
archive( x, y, z );
}
};
外部serialization function
struct MyClass
{
int x, y, z;
};
template<class Archive>
void serialize(Archive & archive,
MyClass & m)
{
archive( m.x, m.y, m.z );
}
内部load/save function
struct MyClass
{
int x, y, z;
template<class Archive>
void save(Archive & archive) const
{
archive( x, y, z );
}
template<class Archive>
void load(Archive & archive)
{
archive( x, y, z );
}
};
外部load/save function
struct MyClass
{
int x, y, z;
};
template<class Archive>
void save(Archive & archive,
MyClass const & m)
{
archive( m.x, m.y, m.z );
}
template<class Archive>
void load(Archive & archive,
MyClass & m)
{
archive( m.x, m.y, m.z );
}
值得注意的是save function必须是const类,否则Cereal就会报错。
另外当把序列化/反序列化函数放在class外部时,确保它们和class在同一个变量域中。
私有的序列化函数
前文中提到序列化函数也可以是私有的,使用的实力代码如下:
#include <cereal/access.hpp>//必须包含
class MyCoolClass
{
private:
int secretX;
friend class cereal::access;//必须声明
template <class Archive>
void serialize( Archive & ar )//现在此函数已经是私有的了,不可从外部访问
{
ar( secretX );
}
};
load/save function同理。
load_minimal函数和save_minimal函数
首先解释一个这两个函数有啥用。load_minimal函数和save_minimal函数仅仅保存class中每个数据类型对应的一个值。这以为着人们可以更加方便的通过阅读XML/JSON来了解所序列化对象的数据结构。
内部load_minimal/save_minimal function
struct MyData
{
double d;
template <class Archive>
double save_minimal(
Archive const & ) const
{
return d;
}
template <class Archive>
void load_minimal( Archive const &,
double const & value )
{
d = value;
}
};
外部load_minimal/save_minimal function
struct MyData
{
double d;
};
template <class Archive>
double save_minimal(
Archive const &,
MyData const & md )
{
return md.d;
}
template <class Archive>
void load_minimal( Archive const &,
MyData & md,
double const & value )
{
md.d = value;
}
下边给出一个使用load_minimal/save_minimal function的例子。其中分别包含一个常规的load/save function和load_minimal/save_minimal function。
#include <cereal/archives/json.hpp>
#include <iostream>
struct Minimal
{
std::string myData;
template <class Archive>
std::string save_minimal( Archive const & ) const
{ return myData; }
template <class Archive>
void load_minimal( Archive const &, std::string const & value )
{ myData = value; }
};
struct Normal
{
std::string myData;
template <class Archive>
void serialize( Archive & ar )
{ ar( myData ); }
};
int main()
{
Minimal m = {"minimal"};
Normal n = {"normal"};
cereal::JSONOutputArchive ar( std::cout );
ar( CEREAL_NVP(m), CEREAL_NVP(n) );
}
输出结果如下:
{
"m": "minimal",
"n": {
"value0": "normal"
}
}