在C ++中反序列化对象

时间:2012-06-17 16:59:13

标签: c++ serialization deserialization ostringstream

我知道如何按以下方式序列化对象:

void encodeMsg(char **msg, const ConnectionParams& params)
{
    std::ostringstream oss;
    if (!(oss << params))
    {
        //failure
    }
    msg = oss.str();
}

如何将消息反序列化回对象?

意思是我想要这个方法:

ConnectionParams encodeMsg(char *msg)
    { ... }

所以我没有一个instringstream对象......我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

类似的东西:

ConnectionParams decodeMsg(char *msg)
{
  ConnectionParams ret;
  std::istringstream iss(msg);
  iss >> ret;
  return ret;
}

假设这个类可以使用operator<<进行序列化,并提供对称相反的操作operator>>。在不知道其内部结构的情况下无法序列化任意C ++对象,在这个答案中我假设这些操作已经由类提供程序实现。

另请注意,您应该将ConnectionParams作为参考传递,例如:

void encodeMsg(char *msg, ConnectionParams& ret);

此外,您的encodeMsg错误,有更好的机会工作:

void encodeMsg(char **msg, const ConnectionParams& params)
{
    ....
    *msg = oss.str();
}

甚至这是错误的,因为oss.str()从oss返回一个内部指针,你不能将它返回给调用者,因为oss将在函数返回时被销毁,并且指针将无效。你最好返回一个std :: string或类似的东西。

编辑: 如果该类没有提供序列化和反序列化的方法怎么办?在足够简单的类上,并且没有在堆上分配指针,也没有文件描述符,也没有在构造函数和析构函数上有花哨的行为,你可以用与旧C结构相同的方式完成它:解释它的所有字节作为缓冲区。请注意,这是危险的,类型不安全,并且缓冲区可能无法在不同的编译器/体系结构之间互操作。

// DISCLAIMER: Untested code!

class A {
  int plain_variable;
  char palin_array[50];
};
// Class A is ok to serialize this way

class B {
  A plain_object_array[10];
  double another_plain_variable;
};
// Class B is ok to serialize this way

class C {
  float plain_object;
  std::string fancy_string;
};
// Class C is *NOT* ok to serialize this way, because it contains an string,
// which, in turn, contains a heap allocated pointer

template<class T>
void serialize(const T& obj, std::string& buff)
{
  const char *accessor = (const char *)&obj;
  std::string tmp(accessor, sizeof(obj));
  std::swap(buff, tmp);
}

template<class T>
void deserialize(const std::string& buff, T& obj)
{
  char *accessor = (char *)&obj;
  std::copy(buff.begin(), buff.end(), accessor);
}

请参阅此方案的工作条件,以便您不太可能将其与第三方提供的类一起使用。最后,您可能需要存储自己重建对象所需的所有数据,并处理这些数据。