【问题标题】:Serializing struct containing char*序列化包含 char* 的结构
【发布时间】:2010-04-28 13:49:13
【问题描述】:

序列化 char* 字符串时出错error C2228: left of '.serialize' must have class/struct/union 我可以使用 std::string 然后从中获取 const char*。但我需要 char* 字符串。

【问题讨论】:

  • 我们可以看看你尝试序列化的代码吗?
  • 完全正确需要更多信息。
  • char* 没有包含足够的序列化代码信息。其中没有数组长度。通常,char* 可能不是字符串。像 char[MAX_LENGTH] 这样的东西呢?

标签: c++ serialization boost


【解决方案1】:

错误信息说明了一切,boost 序列化不支持序列化指向原始类型的指针。

你可以在商店代码中做这样的事情:

int len = strlen(string) + 1;
ar & len;
ar & boost::serialization::make_binary_object(string, len);

并在加载代码中:

int len;
ar & len;
string = new char[len]; //Don't forget to deallocate the old string
ar & boost::serialization::make_binary_object(string, len);

【讨论】:

  • 能否详细说明//Don't forget to deallocate the old string
【解决方案2】:

没有办法将 pointer 序列化到 boost::serialization 中的某些东西(我怀疑,也没有 实际 方法可以做到这一点)。指针只是一个内存地址,这些内存地址通常是特定于对象的实例,而且,真正重要的是,这个地址不包含停止序列化的信息。

你不能只对你的序列化器说:“嘿,从这个指针中取出一些东西并序列化这个东西。我不在乎它有多大,就去做吧……” em>

首先,您的问题的最佳解决方案是使用std::string 或您自己的字符串实现来包装您的char*。第二种方法意味着为char* 编写特殊的序列化例程,而且我怀疑它通常会与第一种方法一样。

【讨论】:

  • 实际上将指向类/结构的指针序列化就可以了(只要您为它声明了serialize 函数)。
【解决方案3】:

试试这个:

struct Example
{
  int i;
  char c;
  char * text; // Prefer std::string to char *

  void Serialize(std::ostream& output)
  {
     output << i << "\n";
     output << c << "\n";

     // Output the length of the text member,
     // followed by the actual text.
     size_t  text_length = 0;
     if (text)
     (
         text_length = strlen(text);
     }
     output << text_length << "\n";
     output << text << "\n";
  };

  void Input(std::istream& input)
  {
     input >> i;
     input.ignore(1000, '\n'); // Eat any characters after the integer.
     input >> c;
     input.ignore(1000, '\n');

     // Read the size of the text data.
     size_t  text_length = 0;
     input >> text_length;
     input.ignore(1000, '\n');
     delete[] text; // Destroy previous contents, if any.
     text = NULL;
     if (text_length)
     {
         text = new char[text_length];
         input.read(text, text_length);
     }
};

由于指针不可移植,因此必须改为写入数据。

文本称为可变长度字段。可变长度字段通常以两种数据结构输出(序列化):长度后跟数据或数据后跟终端字符。首先指定长度允许使用块读取。对于后一种数据结构,数据必须一次读取一个单元,直到 终端字符 被读取。 注意:后一种数据结构也意味着终结符不能是数据项集合的一部分。

序列化需要考虑的一些重要问题:
1. 使用与平台无关的格式,例如数字的 ASCII 文本。
2. 如果平台方法不可用或不允许,请为数字定义精确规范,包括字节序最大长度
3. 对于浮点数,规范应将浮点数的组成部分视为必须遵守数字规范(即指数、大小和尾数)的单个数字。
4. 更喜欢固定长度的记录而不是可变长度的记录。
5. 更喜欢序列化到缓冲区。然后对象的用户可以创建一个或多个对象的缓冲区并将缓冲区写为一个块(使用一个操作)。输入也是如此。
6. 更喜欢使用数据库而不是序列化。虽然这对于网络来说可能是不可能的,但尽一切努力让数据库管理数据。 数据库可能能够通过网络发送数据。

【讨论】:

  • +1:节省使用 boost 与包含非结构/类类型数据的结构/类的开销。
猜你喜欢
  • 2021-07-28
  • 2014-10-04
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多