boost:序列化重构(加载)

2024-02-28

我正在使用 boost:serialization 将数据结构保存到文件中。实际数据是类和子类的指针向量。 然而,被序列化的类的构造函数将另一个实例化的类 Agent 作为参数,该类 Agent 是控制与模拟 API(webots)通信的对象。 我看到在 boost::serialization 示例中,可序列化对象需要一个空的构造函数 class() {};用于重建。然而,这对我来说是不切实际的。如何使用重构但包含与 API 通信的对象? 可序列化类之一具有以下构造函数:

State(Agent &A, ACTION_MODE const& m);

我从 boost 文档中的示例中看到我需要这样的东西:

State() {};

然而 Agent &A 必须作为参数传递。 我应该找到解决这个问题的方法(使用外部、单例、全局对象)还是有办法在重建时修改这种行为?我确信我在这里遗漏了一些东西。

谢谢

编辑: 也许我解释得不够清楚。尝试通过重建序列化数据“加载”时收到错误消息。

error: no matching function to call State::State()

这就是让我研究 boost::serialize 代码的原因,并认为它正在调用构造函数或复制运算符。 如何让它使用特定的构造函数来序列化数据并将 Agent 引用 &a 作为参数?

EDIT#2:

template <class S, class P, class A> void Task<S,P,A>::save(const char* file)
{
  std::ofstream ofs(file);
  assert(ofs.good());
  boost::archive::text_oarchive oa(ofs);
  oa << states;
  ofs.close();
}

template <class S, class P, class A> void Task<S,P,A>::load(const char* file)
{
  std::ifstream ifs(file);
  boost::archive::text_iarchive ia(ifs);
  ia >> states;
  ifs.close();
}

States 是 boost::serialization::access 的朋友,并且具有序列化功能。 保存工作正常,加载是问题。 状态是:boost::ptr_vector<S> states;其中 S 是 State 多态类的一种类型。

State是基类并且具有“序列化”

template <class Archive>
void State::serialize(Archive& ar, const unsigned int version)
{
  ar & accel.Xaxis & accel.Yaxis & accel.Zaxis;
  ar & gyro.Xaxis & gyro.Yaxis & gyro.Zaxis;
  ar & gps.Yaxis;
  ar & positions;
  ar & reward & value & hash_value;
}

guState 继承自 State。

template <class Archive>
void guState::serialize(Archive& ar, const unsigned int version)
{
  ar & boost::serialization::base_object<State>(*this);
  ar & accel.Xaxis & accel.Yaxis & accel.Zaxis;
  ar & gyro.Xaxis & gyro.Yaxis & gyro.Zaxis;
  ar & gps.Yaxis;
  ar & positions;
  ar & reward & value & hash_value;
}

Accel、gyro、gps 是具有 3 个双变量的简单结构。它们在上面被连载了^^。 职位是一个std::map<std::string,float> positions;

查看序列化的文本文件,一切都显示正常。 我无法理解为什么它在尝试加载文件时调用构造函数。

EDIT#3:

基础构造函数是:

State(Agent &A, ACTION_MODE const& m);

派生构造函数是:

guState::guState(Agent& A, ACTION_MODE const& m) : 
State(A, m)
{
...
}

Agent引用&A,保存在每个State(或派生State)中,指的是从模拟API获取的一个对象。它控制着一个机器人。我无法序列化它,序列化它也没有意义。

当我使用时:

namespace boost { namespace serialization {
  template <class Archive>
    void save_construct_data(Archive & ar,const guState* d,const unsigned int file_version)
    {
      ar << guState::caller;
      ar << guState::mode;
    }
   template <class Archive>
   void load_construct_data(Archive & ar, guState* d,const unsigned int file_version)
   {
      Agent &a;
      ACTION_MODE &m;
      ar >> a;
      ar >> m;
      ::new(d) guState(a,m);
   }
  }
}

我收到以下错误:

invalid use of non-static data member State::caller
invalid use of non-static data member State::mode

引用构造函数中使用的引用。 和:

error: 'a' declared as reference but not initialized
error: 'm' declared as reference but not initialized

正如您所看到的,尝试保存对 Agent 的引用是没有意义的,因为每次启动应用程序时该引用(即使可以保存或序列化)可能会有所不同。

在加载构造数据时,除了我可能使用错误的语法之外,从对代理的序列化引用构造是没有意义的。

我相信我需要的是一种告诉 load_construct_data 如何获取对代理的引用(在初始化代理对象之后)并使用该引用来构造数据的方法。

这有任何意义吗 ?您认为这可行吗?

EDIT#4

namespace boost { namespace serialization {
  template <class Archive>
    void save_construct_data(Archive & ar,const guState* d,const unsigned int file_version)
    {
      ar <<  guState::caller;
    }
   template <class Archive>
   void load_construct_data(Archive & ar, guState* d,const unsigned int file_version)
   {
      Agent * a;
      ACTION_MODE mode = RAND_SING;
      ar >> a;
      ::new(d) guState(*a,mode);
   }
  }
}

它将不允许序列化 guState::caller

我还使 Agent 类可序列化,并重载了 Agent 的 load_construct_data 和 save_construct_data,以便从模拟应用程序请求一个新的 Agent 实例来控制 API。


EDIT:

我认为我们都错过了手册的一部分:该部分非默认构造函数 here http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/index.html。为了使它工作,你需要save_construct_data and a load_construct_data功能。就这些好友探索的地方而言,存在一些技术细节here https://stackoverflow.com/q/4112075/498253.

另外,你说你在尝试加载时遇到了这个问题,但你可以保存得很好。这让我觉得你可能忽略了

BOOST_CLASS_EXPORT_GUID(state, "state")

一旦您进行负载编译,此遗漏可能会导致分段错误(请参阅手册的导出部分)

为了确保我没有弄错,我做了一个编译示例,我添加了它以备不时之需。

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

#include <boost/serialization/export.hpp>
#include <iostream>
#include <fstream>

//base class
struct base
{
  base(double d) : m_d(d) {}
  virtual double run() = 0;
private:

  friend class boost::serialization::access;
  double m_d;
  template <class Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & m_d;
  }
};

//forward declare the save construct data before friending it 
// (something about friend being in a different namespace)
class derived;
namespace boost { namespace serialization {
template<class Archive>
inline void save_construct_data(Archive & ar, const derived * t, const unsigned int file_version);
}}


//derived class with non-default constructor
struct derived : public base
{
  derived(double a , double b) : 
    base(a+b),
    m_a(a),m_b(b),m_c(a*b) 
  {}
  //some checks
  double get_a() const {return m_a;}
  double get_b() const {return m_b;}
  double get_c() const {return m_c;}

  double run(){return 1.0;}
private:

  friend class boost::serialization::access;
  template<class Archive> 
  friend void boost::serialization::save_construct_data(Archive & ar, const derived * t, const unsigned int file_version);

  template <class Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & boost::serialization::base_object<base>(*this);
    //only need to return c, a and b already done for constructor
    ar & m_c;
  }
  double m_a, m_b, m_c;
 };

//Save and load the data required for the constructor.
namespace boost { namespace serialization {
  template <class Archive>
    inline void save_construct_data(
                    Archive & ar,const derived* d,const unsigned int file_version
                    )
    {
      // save data required to construct instance
      ar << d->m_a;
      ar << d->m_b;
    }
    template <class Archive>
    inline void load_construct_data(
                        Archive & ar, derived* d,const unsigned int file_version
                        )
    {
      double a,b;
      ar >> a;
      ar >> b;
    // invoke inplace constructor to initialize instance of my_class
      ::new(d) derived(a,b);
    }

  }
}

//register the derived class with boost.
BOOST_CLASS_EXPORT_GUID(derived, "derived")

int
main  (int ac, char **av)
{
  std::ofstream ofs("filename");
  base* p = new derived(2,3);

  // save data to archive
  {
    boost::archive::text_oarchive oa(ofs);
    oa << p;
  }

  // ... some time later restore the class instance to its orginal state
  base* p2;
  {
     std::ifstream ifs("filename");
     boost::archive::text_iarchive ia(ifs);
     ia >> p2;
  }

  derived* d = static_cast<derived*>(p2);
  std::cout<<"p2 vals are: "<<d->get_a()<<" "<<d->get_b()<<" "<<d->get_c()<<std::endl;

}

旧回复:

不确定我完全理解你的问题(更完整的例子会对我有帮助)- 当您序列化对象时,构造函数通常不会进入其中:您序列化原始数据?

你的意思是你不想序列化对象的所有原始数据,而只想在反序列化对象时(使用构造函数)再次重建它?如果是这样,那么您可以通过序列化重建所需的数据并拆分保存和加载操作来完成此操作。

struct my_class
{
  my_class(Agent& A, ACTION_MODE const & m)
    : m_state(A,M)
  {}


private: 

  State m_state;

  friend class boost::serialization::access;
  void save(Archive & ar, const unsigned int version) const
  {
      // note, version is always the latest when saving
      Agent tmp_A = m_state.get_A();
      ACTION_MODE tmp_m = m_state.get_m();
      ar & tmp_A; 
      ar & tmp_m;
  }
  template<class Archive>
  void load(Archive & ar, const unsigned int version)
  {
      Agent tmp_A;
      ACTION_MODE tmp_m
      ar & tmp_A; 
      ar & tmp_m;
      m_state = State(tmp_A,tmp_m);
  }
  BOOST_SERIALIZATION_SPLIT_MEMBER()
}

这有帮助吗,还是我错过了重点?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boost:序列化重构(加载) 的相关文章

  • IIS应用程序池回收+quartz调度

    我正在 IIS 7 5 上运行一个 Web 应用程序 它需要偶尔回收 否则内存使用情况会失控 这是我正在研究的问题 当它回收时 它实际上不会运行 直到另一个请求到来 而quartz不会运行 有没有办法让IIS在回收应用程序池后立即自动启动1
  • C# 打印问题(RichTextBox)

    我想打印我的 RichTextBox eintragRichTextBox 的内容 我现在有这个代码 private void druckenPictureBox Click object sender EventArgs e PrintD
  • 添加 Nullable int 时保持 null?

    我想添加可为空的int 并保留null当所有值都是null 我想要这个结果 1 2 3 1 null 1 null null null O null 0 问题是 如果我将一个值与 null 相加 结果为 null int i1 1 int
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 删除是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 C 编程 free 如何知道要释放多少 https stackoverflow com questions 1518711 c programming how does free know how m
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 引用/指针失效到底是什么?

    我找不到任何定义指针 引用无效在标准中 我问这个问题是因为我刚刚发现 C 11 禁止字符串的写时复制 COW 据我了解 如果应用了 COW 那么p仍然是一个有效的指针并且r以下命令后的有效参考 std string s abc std st
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • 如何在 winforms 应用程序的主屏幕显示之前显示欢迎屏幕?

    我想在应用程序启动时加载欢迎屏幕 然后用户单击欢迎屏幕上的按钮 然后关闭欢迎屏幕 最后显示主屏幕 static void Main startup method being called Application EnableVisualSt
  • 为什么以下 C 程序会出现总线错误?

    我认为这是第一个失败的 strtok 调用 好久没写C了 有点不知所措 非常感谢 include
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 如何将 SQL“LIKE”与 LINQ to Entities 结合使用?

    我有一个文本框 允许用户指定搜索字符串 包括通配符 例如 Joh Johnson mit ack on 在使用 LINQ to Entities 之前 我有一个存储过程 该存储过程将该字符串作为参数并执行以下操作 SELECT FROM T

随机推荐

  • 鼠标悬停时出现棘手的延迟

    这就是我目前所拥有的 cart summary mouseenter function flycart delay 500 slideDown fast flycart mouseleave function flycart delay 5
  • SQL Server 查询:使用 JOIN 包含 NULL 值

    我需要有关以下 SQL Server 查询的帮助 其中列 a TAProfileID 和 c CountryCode 在数据库中具有 NULL 值 我希望我的 JOIN 语句返回 NULL 值 如果存在 SELECT a Reservati
  • 比较表中的行对

    我可以在比较同一个表中的行的查询上使用一些补救帮助 我正在修改我们的代码以推送到 Postgres 并建立了一个测试床来使用我们的旧代码和新代码进行推送 行数很好 但这并不能告诉我数据是否相同 为此 我意识到我可以使用内置功能来获取行的哈希
  • 在 json 字符串化数组对象时排除对象属性

    嘿我有一个像这样的数组对象 public public private private properties instance 这里最外面的数组包含 A 类的对象 它有一些公共 props 一些私有 porps 它还包含一个包含 B 类对象
  • 为什么 .gitignore 不包含以 ! 为前缀的文件

    我的 gitignore 文件内容如下 build glucosia xcodeproj glucosia xcodeproj project pbxproj core plot framework build core plot fram
  • 由于某些许可证尚未被接受,无法安装以下 Android SDK 包

    我需要在我的 Android 项目中集成一个持续集成系统 我发现 CodeShip 是一个很好的选择 因此我创建并配置了一个项目来使用以下脚本编译我的 Android 应用程序 Install java 8 jdk switcher hom
  • 实体框架中的自引用/父子关系

    我读了很多程序员的帖子 其中涉及到无法确定相关操作的有效顺序 由于外键约束 模型要求或存储生成的值 可能会存在依赖关系 在实体框架中使用自引用关系时出现异常 我正在努力建立亲子关系 public class Category public
  • 在 mySQL 中插入带有特殊字符的 JSON 编码值失败

    我正在尝试使用 PDO 执行此查询 UPDATE categories SET keywords bg keyword1 u0431 u044a u043b u0433 u0430 u0440 u0441 u043a u0438 WHERE
  • 如何检测用户是否选择取消InputBox VBA Excel

    我有一个输入框要求用户输入日期 如果用户单击 取消 或关闭输入对话框而不是按 确定 如何让程序知道停止 就像是if str vbCancel then exit sub 目前 用户可以点击 确定 或 取消 但程序仍然运行 str Input
  • Pandas scatter_matrix - 绘制分类变量

    我正在查看 Kaggle 竞赛中著名的泰坦尼克号数据集 http www kaggle com c titanic gettingStarted data http www kaggle com c titanic gettingStart
  • 使用Mercurial (hg),如何只推送一个文件或一个目录?

    使用 Mercurial 我们可以使用以下命令提交一个文件 hg commit file rb 或 1 个文件夹 hg commit foldername 但是我们如何才能只推出 1 个文件或 1 个文件夹呢 整个项目可以使用 hg pus
  • Flutter:ClipRRect 与带有 BoxDecoration 的容器

    我知道 ClipRRect 有其他选项 例如自定义剪辑器 但如果我只需要一个简单的边界半径 性能上有什么区别吗 哪一款更值得推荐呢 如果您的目标是创建圆形边框 则必须仅在最后一种情况下使用剪裁器 此时容器可能无济于事 例如 图像可以在圆形边
  • Java servlet - 会话清理 (HttpServletRequest)

    关于 java servlet 的一般问题以及处理请求的最佳方法 如果我从远程服务器请求中调用 doGet 方法 protected void doGet HttpServletRequest request HttpServletResp
  • 学习 Javascript 与 jQuery

    我拿到了 Wrox Beginning JavaScript 3rd Edition 并想从头开始学习它 然后我的老板走过来说 何必呢 学习 jQuery 尽管我是一个新手 对 ASP net vb net 一些 C 和基本 HTML 的了
  • 如何在CRM 2011中从多对多实体关系中创建和删除数据?

    如何在crm 2011中从多对多实体关系中创建和删除数据 Code QueryExpression qry new QueryExpression qry EntityName entity1 entity2 qry ColumnSet n
  • 更新模型时如何更新counter_cache?

    我有一个简单的关系 class Item belongs to container counter cache gt true end class Container has many items end 假设我有两个容器 我创建一个项目并
  • x86 asm 中 NOT 指令的简单示例

    有人能解释一下 x86 汇编器中 NOT 指令的具体作用吗 在我所知道的编程语言中 NOT 用于检查特定状态是否不正确 例如 if Isset var 但在汇编器中 运算符似乎做了其他事情 我不明白操作数到底是做什么用的 有人可以用一个简单
  • 错误 TS1127:在 Angular 7 中运行 Karma 测试时出现无效字符

    我收到错误error TS1127 Invalid character在 Visual Studio Code 终端中 为 Angular 7 应用运行 Karma 测试时 命令行版本 7 3 9 I have 一份 Karma 测试规范在
  • Scapy:处理部分 TLS 段

    我正在尝试使用 Scapy 从 pcap 中提取 TLS 元数据 我能够成功解析数据包和单个消息 例如 client hello server hello 等及其字段 我遇到的问题是当 TLS 记录分布在多个 TCP 数据包 段时 这种情况
  • boost:序列化重构(加载)

    我正在使用 boost serialization 将数据结构保存到文件中 实际数据是类和子类的指针向量 然而 被序列化的类的构造函数将另一个实例化的类 Agent 作为参数 该类 Agent 是控制与模拟 API webots 通信的对象