【问题标题】:Best serialization method for my data structure?我的数据结构的最佳序列化方法?
【发布时间】:2017-10-15 22:53:58
【问题描述】:

这里曾经问过的第一个问题。我尝试过使用 Boost,但无法弄清楚它如何与我的结构一起工作。另外,即使在将其添加到其他库等之后,.lib 缺失错误也会不断发生。就像它在几次运行中工作一样,然后又突然出现。第一次通过创建一个新项目来解决它,但我没有时间继续这样做。

无论如何,我已将代码从 Visual Studio 移至 QT Creator。现在我正在阅读一些关于 XML 或 JSON 的内容,并考虑是否应该尝试实现它?

问题是我有一整天的时间来解决我明天到期的最终项目的序列化问题。一旦我有了这个,我需要制作一个我希望会更容易的 GUI。提前致谢。以下是我使用 Boost 的最佳尝试

Hotel.h

class guestBook {
    protected:
    friend class roomBook;
    friend class hashMap;
    struct guest {
        int guestKey;
        string firstName;
        string lastName;
        guest *next;
        template<class Archive>
        void serialize( Archive & ar )
        {
            ar( guestKey, firstName, lastName);
        }
    };
    guest* guestHashTable[tableSize];
    public:
    void writeGuestTable();
    void readGuestTable();
    void addGuest(string firstName, string lastName);
    int numberOfItemsInBucket(int index);
    void retrieveGuestID();
};
guestBook.cpp
void hashMap::writeGuestTable() {
    for(int x=0;x<tableSize;x++){
       guestHashTable[x] = new guest;
       guestHashTable[x]->guestKey = 0;
       guestHashTable[x]->firstName = "empty";
       guestHashTable[x]->lastName = "empty";
    }
    ofstream os("guestTable.txt", ios::binary);
    cereal::BinaryOutputArchive archive( os );
    guest myData;
    archive( myData );
}

【问题讨论】:

  • 欢迎来到 Stack Overflow。请花时间阅读The Tour 并参考Help Center 中的材料,您可以在这里问什么以及如何问。
  • 你为什么要滚动你自己的 hashmap 结构?尝试使用标准库中的容器,例如 std::map。这将为您节省大量调试时间并避免重新发明轮子。
  • @tadman 我的导师让我们对自己的哈希图结构进行硬编码,所以我关注了一些 youtube 视频。这给了我将它延续到我的最终项目的想法,但你可能是对的,也许使用 std 库会使事情变得更容易。我只需要花一点时间来学习它。你会为我上面的结构推荐 std::map 吗?
  • 如果您正在制作查找表,std::map 就是您想要的。根据您的需要,还有许多其他具有不同属性的容器。如果您出于学术原因滚动自己的实现,请查看标准库如何定义接口。地图本身和它所包含的数据之间通常会分离关注点,从而简化您的设计。使std::map 工作相似具有教育意义,因为您有一个工作参考实现可供比较。
  • @RyanNguyen 我的导师让我们硬编码自己的 hashmap 结构 -- 然后你应该写一个通用的,而不是硬连线到你的 guestBook 结构中。

标签: c++ visual-studio qt serialization boost


【解决方案1】:

我强烈推荐Cereal C++ 序列化库。与 boost.serialization 相比,它的优势包括:仅标头、更新/更好的模板编程结构、json 存档和可移植二进制存档。它唯一的缺点(在我看来)是:它需要 C++11(对于 Visual Studio 2015 或更新版本),并且它只支持智能指针的序列化(即,不能序列化原始指针——但这简化了对象跟踪并保持档案中的杂物,这有助于一个漂亮、干净的 json 档案)。

这是来自Quick Start Page的示例

struct MyClass
{
  int x, y, z;

  // This method lets cereal know which data members to serialize
  template<class Archive>
  void serialize(Archive & archive)
  {
    archive( x, y, z ); // serialize things by passing them to the archive
  }
};

谷物也有Standard Library Support。如果您有一个std::vector 的guestBook 对象,那么只需#include &lt;cereal/types/vector.hpp&gt;(除了guestBook::serialize 方法)就可以将向量写入存档。

【讨论】:

  • 好的,我已经尝试在我的程序中实施谷物。假设我正在序列化 100 个结构的整个表,我的代码看起来不错吗?在 OP 中编辑它
  • 没有。函数签名不正确。它需要是一个模板方法。示例MyClass 与您正在做的非常接近。
  • 我仍然不明白如何序列化 100 个对象。我已将模板和序列化方法放在结构内。我是否只是通过 for 循环创建结构 100 次。在这一点上我真的不知道我在做什么:(
  • 我已经更新了 OP 中的代码,它运行时没有任何错误。决定将档案写为二进制文件,因为我只需要在运行程序时访问它。基本上我想在关闭程序时保存整个表并在打开程序时加载它,以便我可以添加/删除客人。事情是我检查了文本文件并看到了一些二进制位,所以我确定不是整个表都被归档并写入文件。
【解决方案2】:

在 Qt 中(正如您在标签中提到的),我更喜欢使用 QDataStream 序列化类成员,而不是添加新库(实际上添加了新错误!!),同时也受益于 Qt 的一些不错的功能,如隐式共享。

QDataStream 生成二进制序列化数据,并且知道泛型类型和 Qt 类,例如 QByteArray 和 QString ...,并且还保证所有平台中的数据类型具有相同的宽度和大小,因此可以用作跨平台解决方案。

class  TestClass{
    QString strA;
    QByteArray ba;
    int a;
    quint32 b;

    QByteArray serialize(){
        QByteArray serializedData;
        QDataStream ds(&serializedData, QIODevice::WriteOnly);

        ds << strA;
        ds << ba;
        ds << a;
        ds << b;

        return serializedData;
    }

    static TestClass deserialize(QByteArray serializedData){
        TestClass deserializedClass;

        QDataStream ds(&serializedData, QIODevice::WriteOnly);

        ds >> deserializedClass.strA;
        ds >> deserializedClass.ba;
        ds >> deserializedClass.a;
        ds >> deserializedClass.b;

        return deserializedClass;

    }
}

【讨论】:

    猜你喜欢
    • 2015-06-23
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2013-06-22
    相关资源
    最近更新 更多