【问题标题】:Preferred way to serialize an object with C++使用 C++ 序列化对象的首选方法
【发布时间】:2012-10-07 03:41:06
【问题描述】:

Java 有一种非常简单的方法来序列化对象。在 C++ 中找不到类似的东西。 我使用 ifstream 和 ofstream 找到了 Boost Serializationbasic approach

我有一个任务类,它有一个标题、ID、状态和日期/时间。我想在类中实现一个序列化函数,以二进制模式保存该对象。 但我想将类的多个实例保存在一个二进制文件中。假设是一个 Task 数组。

在类上实现序列化方法会是一个好方法吗?它一次只会序列化一个,如果我使用 ifstream/ofstream,它看起来不太好,因为我会经常打开和关闭文件。此外,每个任务都将保存在不同的文件中。

Boost 的序列化看起来不错,但如果可能的话,我最好避免第三方依赖。

最好的方法是什么?

我的班级标题:

#ifndef TASK_H
#define TASK_H

class Task {
    public:
        enum Status { COMPLETED, PENDIENT };
        Task(std::string text);
        ~Task();
        // SETTERS
        void setText(std::string text);
        void setStatus(Status status);
        // GETTERS
        const std::string getText() const;
        const bool getStatus() const;
        const int getID() const;
        const int getCount() const;
        const std::string getDate() const;
        const std::string getTime() const;
        // DATE
        const int getDay() const;
        const int getMonth() const;
        const int getYear() const;
        // TIME
        const int getSecond() const;
        const int getMinute() const;
        const int getHour() const;
        // UTILS
        //serialize
        const void printFormatted() const;
        // OVERLOAD
        bool operator==( const Task &text2 ) const;
    private:
        void setID();
        static int sCount;
        int id;
        std::string text;
        Status status;
        tm *timestamp;
};

#endif

【问题讨论】:

  • 只要你的对象是单一的并且简单的序列化就是小菜一碟。开始添加对其他对象的内部引用,随着身份和所有权问题开始出现丑陋的一面,事情会很快变得复杂。
  • 将时间戳记为 tm* 而不是 tm 有什么具体原因吗?

标签: c++ serialization


【解决方案1】:

如果您只有一个非常简单的类要序列化,那么实现一个序列化函数来写出您需要保存的少数成员并不难。您没有给出显示您的类的代码示例,但是只要不涉及指针,它应该相对容易一些成员。如果您写出序列化对象的数量,然后写出其中包含的数据,那可能就足以满足您的目的了。

如果您想自己实现序列化,我将有一个外部函数(可能是您班级的朋友)处理 Task 数组的序列化,而不是尝试将数组序列化放入您的班级。您可以做的是在您的类中添加一个serialiseObject() 函数来序列化单个对象,然后从数组序列化函数中重复调用它。这比将数组序列化也绑定到类本身要简洁得多。

一旦你开始序列化稍微复杂一点的 C++ 对象,尤其是那些包含引用和指针的对象,序列化很快就会成为一个难题,你真的非常想使用一个已经很好的现有第三方机制经过测试。

也就是说,作为一个以 C++ 开发为生的人,我认为对 boost 的依赖是正常的,而不是我想要避免的第三方库。 Boost 为您提供了许多额外的功能,我认为它是“我的标准库”的一部分。

【讨论】:

  • Boost 是迄今为止序列化的最佳选择,我认为它也几乎是标准的。
  • 我同意(而且我什至不是特别喜欢 boost,但他们的序列化系统简直是太棒了)。
  • 我添加了我的班级标题。我使用指针私有变量,如您所见的时间戳。所以我应该坚持boost吗?我是否在类中编写序列化方法,并按一个序列化?还是我单独写,然后传一个Task数组?
  • 我已经在上面概述了如果我要自己编写序列化代码,我将如何构建它。我会考虑摆脱指向 tm 的点并用聚合的 tm 替换它,因为这确实使序列化代码的实现更加简单。但是,如果这不是您用来学习序列化之类的“玩具”项目,我可能仍会使用 boost。
【解决方案2】:

由于在 C++ 中没有用于序列化数据的标准,因此“首选”方式是您更喜欢的方式。 Boost 是完全可以接受的,除非您的项目明确禁止使用第三方库,在这种情况下您当然可以自行开发。

如果您选择自己滚动,请确保您的序列化器和反序列化器不会自行打开和关闭流。相反,调用者需要将流传递给他们。请参阅this link 了解更多信息。

【讨论】:

    【解决方案3】:

    我还使用 Google protobuf 进行序列化。虽然不是严格的序列化,但 Google protobuf 可以非常高效且跨平台的数据容器。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 2020-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多