使用引导序列化从成员函数反序列化

Posted

技术标签:

【中文标题】使用引导序列化从成员函数反序列化【英文标题】:Using boot serialization to deserialize from a member function 【发布时间】:2019-03-26 02:04:07 【问题描述】:

我想使用 boost 序列化来序列化/反序列化类实例中的数据。想法是类应该封装数据,以及序列化和反序列化的细节。这适用于使用ar << this 进行序列化,但使用ar >> this 进行类似的反序列化会产生编译错误

error: cannot bind non-const lvalue reference of type ‘const q*&’ to an rvalue of type ‘const q*’

以下是完整的工作代码,我的不可编译的restoreit 函数被注释掉了。这显然是对我真实代码的简化,但问题是一样的。如何将反序列化方法封装到我的类中?

#include <fstream>
#include <iostream>
#include <map>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>

class q

  public:
    q() : f_()  
    void setup()  f_.insert(std::make_pair(18,10)); 
    int getcount()  return f_.size(); 

    void storeit(const std::string &name)
    
      std::ofstream ofs(name);
      boost::archive::text_oarchive ar(ofs);
      ar << this;
    
    void restoreit(const std::string &name) const
    
      std::ifstream ifs(name);
      boost::archive::text_iarchive ia(ifs);

      // The following line gives the error: cannot bind non-const lvalue reference of type ‘const q*&’ to an rvalue of type ‘const q*’
      // ia >> this;
    

  private:
    std::map<int,int> f_;
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    
      ar & f_;
    
;

int main(void)

  const std::string name = "/tmp/blah";
  q foo;
  foo.setup();
  foo.storeit(name);

  q foo2;
  // I want to use foo2.restore(name) here
  
    std::ifstream ifs(name);
    boost::archive::text_iarchive ia(ifs);
    ia >> foo2;
  

【问题讨论】:

在最新的 gcc 和 clang (godbolt.org/z/ShyPlf) 上编译得很好。您使用的是什么编译器/设置/增强版本? 这是 gcc 8.2.0 和 boost 1.65。发布的代码可以编译,但正如 restoreit() 函数中的注释所说,取消注释该行会中断编译。 【参考方案1】:

您需要从 restoreit 定义中删除 const。恢复时,f_ 映射正在被修改 - 您只能在非常量成员函数中执行此操作。

 void restoreit(const std::string &name)
 
      std::ifstream ifs(name);
      boost::archive::text_iarchive ia(ifs);
      ia >> *this;
 

【讨论】:

以上是关于使用引导序列化从成员函数反序列化的主要内容,如果未能解决你的问题,请参考以下文章

Javascript:字符串化对象(包括类型函数的成员)

使用 XmlSerializer.Deserialize 反序列化时何时调用类构造函数?

json 从遗留属性名称反序列化

C++ 模板工厂构造函数/反序列化

PHP反序列化漏洞

技术分享php反序列化漏洞初探