【问题标题】:Class Serialization methods类序列化方法
【发布时间】:2012-12-21 06:08:29
【问题描述】:

我想用 C++ 序列化对象。一开始我尝试了一个简单的解决方案,我重载了类的<<>>操作符进行序列化;这样我可以选择女巫属性序列化为一个字符串流,然后我可以稍后将相同的字符串流反序列化为另一个相同类型的对象的属性。 这一直有效,直到我意识到如果要序列化的类包含指向其他类的指针,那么我还需要重载它们的 >><< 运算符。

所以我开始想,如果我让对象序列化并逐个字符地遍历它,然后将结果保存到字符串中会怎样。然后稍后获取该字符串并将其重新解释为原始类。这样我就可以序列化任何包含任何类型信息的类,而无需关心它包含什么,也不会重载任何运算符。

我实现了第二种方法,它看起来没问题,但是是吗?

#include <cstdlib>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;

class B
{
public:
      B(int one , int two)
      { 
            this->one = one; 
            this->two = two;
      }
      int one;
      int two;      
};

class A
{
public:
      A(int one , int two, B b)
      {
            this->one = one; 
            this->two = two;
            classB= new B(b);
      }
      int one;
      int two;   
      B* classB;   
};

int main(int argc, char *argv[])
{
    B b(3,4);
    A* a = new A(1,2, b);


    //Serializing 'a'
    char v[sizeof(A)];
    for (int i =0 ;i<sizeof(A);i++)
    {
        v[i] = (reinterpret_cast<char*>(a)[i]);
    }

    char* cp = (char*)malloc(sizeof(char) * sizeof(A));
    for (int i =0 ;i<sizeof(A);i++)
    { 
        cp[i] = v[i];                          
    }

    A* aa = reinterpret_cast<A*>(cp);

    cout << aa->one << endl;
    cout << aa->two<< endl;
    cout << aa->classB->one<< endl;

    free(cp);
    system("PAUSE");
    return EXIT_SUCCESS;

// OUTPUT is as expect:
   1 
   2 
   3
}

那你怎么看?您预见到第二种方法的任何并发症吗?请记住,我对 C++ 非常陌生,我正在尝试开发可行的理论。

【问题讨论】:

  • 你考虑过Boost.Serialization吗?
  • Boost 序列化需要构建库并生成二进制文件,我只能使用仅标头库。另外,我想学习如何做到这一点:)
  • 这个(第二种)方法不适用于存储指针的东西。

标签: c++ serialization


【解决方案1】:

您提到的第二种方法(基本上只是写入和读取数据结构的原始字节)不适用于存储指针的东西。为什么?这样看:

struct S
{
    int* i;
};
S s;

假设您通过执行以下操作写入s 的原始字节:file.write((char*)&amp;s, sizeof(s))。这将写入指针i 的原始值,但不会写入i存储 的值(即*i 返回的值)。如果您尝试重新加载数据结构,i 将指向可能无效的内存区域(因为它是您保存/加载的 i 中存储的 地址,而不是 地址的内容)。

【讨论】:

  • mm 我明白了,但是我确实实现了第二种方法,请看一下(我更新了我的答案)。它似乎可以工作:$ 但你是对的,它不应该。
  • 对不起,我明白了 :) 你是对的,我的代码工作的原因是因为碰巧对象 'a' 在内存中仍然有效并且指针 classB 仍然指向真实数据堆。如果此内存位置以某种方式被清除(例如重新启动),我可以重用序列化数据来恢复对象“a”。
猜你喜欢
  • 2012-04-08
  • 2012-10-14
  • 2014-11-14
  • 2012-11-07
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
相关资源
最近更新 更多