使用序列化 C++ 保存游戏状态

2023-12-06

我有一堂课叫Game其中包含以下内容:

vector<shared_ptr<A>> attr; // attributes
D diff; // differences
vector<shared_ptr<C>> change; // change

我的问题是,如何将这些(保存)写入文件并稍后读取/加载? 我考虑过使用struct里面有这些,然后简单地保存struct但我不知道从哪里开始。

到目前为止,这是我的尝试,只是想保存change。我已经阅读了很多关于这个问题的文章,我的问题(无论如何,其中之一)似乎是我存储的指针在关闭程序后将无效(加上我还在退出之前释放它们的事实) )。

/* Saves state to file */
void Game::saveGame(string toFile) {
    ofstream ofs(toFile, ios::binary);
    ofs.write((char *)&this->change, sizeof(C));

    /* Free memory code here */
    ....

    exit(0);
}; 

/* Loads game state from file */
void Game::loadGame(string fromFile) {
    ifstream ifs(fromFile, ios::binary);
    ifs.read((char *)&this->change, sizeof(C));

    this->change.toString(); // display load results
};

谁能指导我序列化这些数据的正确方向?我只想使用标准包,所以不需要boost.

Thanks.


我不知道如何实现类A, C or D,但这是第一个问题:如何序列化该类的对象。为了C情况下,你需要实现这样的事情:

std::ostream& operator <<(std::ostream& os, const C& c) {
    // ... code to serialize c to an output stream
    return os;
}
std::istream& operator >>(std::istream& is, C& c) {
    // ... code to populate c contents from the input stream
    return is;
}

或者,如果您愿意,可以创建一个write() and read()该类的函数。

好吧,如果你想序列化一个vector<shared_ptr<C>>看起来很明显你不想序列化指针,而是序列化内容。因此,您需要取消引用每个指针并进行序列化。如果在加载之前未知向量的大小(即并不总是相同),则您需要存储该信息。然后,您可以创建一对函数来序列化完整的向量:

std::ostream& operator <<(std::ostream& os, const std::vector<std::shared_ptr<C>>& vc) {
    // serialize the size of the vector using << operator
    // for each element of the vector, let it be called 'pc'
        os << *pc << std::endl; // store the element pointed by the pointer, not the pointer.
    return os;
}
std::istream& operator >>(std::istream& is, std::vector<std::shared_ptr<C>>& c) {
    // read the size of the vector using >> operator
    // set the size of the vector
    // for each i < sizeo of the vector, let 'auto &pc = vc[i]' be a reference to the i-th element of the vector
        C c;                         // temporary object
        is >> c;                     // read the object stored in the stream
        pc = std::make_shared<C>(c); // construct the shared pointer, assuming the class C has copy constructor

    return is;
}

进而,

/* Saves state to file */
void Game::saveGame(string toFile) {
    ofstream ofs(toFile);
    ofs << change;
    ....
}; 

/* Loads game state from file */
void Game::loadGame(string fromFile) {
    ifstream ifs(fromFile);
    ifs >> change;
};

我知道你还有很多事情需要解决。我建议您进行调查以解决这些问题,以便您充分了解如何解决您的问题。

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

使用序列化 C++ 保存游戏状态 的相关文章

  • 如何从字符串中提取子字符串直到遇到第二个空格?

    我有一个像这样的字符串 o1 1232 5467 1232 5467 1232 5467 1232 5467 1232 5467 1232 5467 如何仅提取 o1 1232 5467 要提取的字符数并不总是相同 因此 我只想提取直到遇到
  • 与 for_each 或 std::transform 一起使用时,如何调用 C++ 函子构造函数

    我以前从未使用过 C 函子 所以我只是想了解它们是如何工作的 例如假设我们有这个函子类 class MultiplyBy private int factor public MultiplyBy int x factor x int ope
  • 是否需要销毁运算符删除的形式才能真正销毁对象?

    C 20 添加了破坏形式operator delete区别于std destroying delete t范围 它导致delete表达式在调用之前不再销毁对象operator delete 目的是在显式调用对象的析构函数和释放内存之前 允许
  • 为什么 C 程序使用 Scanf 给出奇怪的输出?

    我目前正在学习 C 编程 并且遇到了这个奇怪的输出 Program will try functionalities of the scanf function include
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • 2个对象,完全相同(除了命名空间)c#

    我正在使用第三方的一组网络服务 但遇到了一个小障碍 在我手动创建将每个属性从源复制到目标的方法之前 我想我应该在这里寻求更好的解决方案 我有 2 个对象 一个是 Customer CustomerParty 类型 另一个是 Appointm
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • wordexp 失败时我们需要调用 wordfree 吗?

    wordexp 失败时我们需要调用 wordfree 吗 在某些情况下 调用 wordfree 似乎会出现段错误 例如 当 wordfree 返回字符串为 foo bar 的错误代码时 这在手册页中并不清楚 我已经看到在某些错误情况下使用了
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • C++ 指针引用混淆

    struct leaf int data leaf l leaf r struct leaf p void tree findparent int n int found leaf parent 这是 BST 的一段代码 我想问一下 为什么
  • 如何从 Windows Phone 7 模拟器获取数据

    我有一个 WP7 的单元测试框架 它在手机上运行 结果相当难以阅读 因此我将它们写入 XDocument 我的问题是 如何才能将这个 XML 文件从手机上移到我的桌面上 以便我可以实际分析结果 到目前为止 我所做的是将 Debugger B
  • 如果将变量设置为等于新对象,旧对象会发生什么?

    假设我们有一个 X 类not有一个超载的operator 功能 class X int n X n 0 X int n n n int main X a 1 an object gets constructed here more code
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • 如何为有时异步的操作创建和实现接口

    假设我有数百个类 它们使用 计算 方法实现公共接口 一些类将执行异步 例如读取文件 而实现相同接口的其他类将执行同步代码 例如将两个数字相加 为了维护和性能 对此进行编码的好方法是什么 到目前为止我读到的帖子总是建议将异步 等待方法冒泡给调

随机推荐