序列化
Cereal需要指明哪些数据需要序列化和反序列化,所以提供了很多函数来完成这个工作。
TLDR版本
Cereal可以单独使用serialization函数,或者使用load/save函数来进行序列化。load函数和save函数也可以被设计成load_minimal函数和save_minimal函数。当把serialization函数放在class外部时,你可以将其设置为私有方法,但是必须友元声明cereal::access,通过宏CEREAL_CLASS_VERSION和给serialization函数添加一个std::uint32_t const version的参数给cereal添加版本信息。
序列化函数
本系列前一节,cereal简单使用基本都是使用实现serialization函数,来完成序列化功能。
下面介绍一下load/save函数实现,通过使用load/save可以让我们在序列化的时候进行一些其他的操作,比如,打印日志,时间等等。
通过一个示例了解一下:
struct MyData
{
MyData(int x, int y) :a(x), b(y) {}
int a;
int b;
//template<class Archive>
//void serialize(Archive & archive)
//{
// archive(a, b);
//}
template<class Archive>
void save(Archive & archive) const
{
cout << "save" << endl;
archive(a, b);
}
template<class Archive>
void load(Archive & archive)
{
cout << "load" << endl;
archive(a, b);
}
};
ofstream out;
{
MyData dm(1, 2);
out.open("./out.json", ios::trunc);
cereal::JSONOutputArchive archive(out);
archive(CEREAL_NVP(dm));
}
out.close();
ifstream in;
MyData dm(0, 0);
{
in.open("./out.json", ios::in);
cereal::JSONInputArchive archive(in);
archive(CEREAL_NVP(dm));
}
它将先后输出:save load
私有序列化函数
struct MyPrivateData
{
private:
int value;
friend class cereal::access; //友元声明
template<class Archive>
void serialize(Archive & archive)
{
archive(value);
}
};
只要声明友元即可。
load_minimal和save_minimal函数
load_minimal函数和save_minimal函数仅仅保存class中每个数据类型对应的一个值,而不保存变量名称。这样就可以更加方便的阅读XML或者Json的序列化数据了。
示例:
struct MinData
{
int value = 0;
template <class Archive>
int save_minimal(Archive const &) const
{
return value;
}
template <class Archive>
void load_minimal(Archive const &, int const & _value)
{
value = _value;
}
};
struct NormalData
{
int value = 0;
template<class Archive>
void serialize(Archive & archive)
{
archive(value);
}
};
//测试代码部分
MinData m;
m.value = 1;
NormalData n;
n.value = 2;
{
cereal::JSONOutputArchive archive(std::cout);
archive(CEREAL_NVP(m), CEREAL_NVP(n));
}
打印输出为: