Cereal library--Serialization函数

原文翻译自: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 functionload_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"
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值