【问题标题】:C++ serialization: overloading insert operator with write()C++ 序列化:用 write() 重载插入运算符
【发布时间】:2012-11-06 20:36:13
【问题描述】:

我有一个简单的类,其中包含一个动态分配的数组,我需要对其进行序列化,以便将其存储在二进制文件中。由于数组的原因,我不能使用 sizeof(MyClass) 来简单地分配缓冲区。

类如下所示:

class ReplayFrame
{
public:
    // ...

private:
    int dataType_;
    int timeStamp_;
    int frameNumber_;
    size_t dataSize_;
    char* data_;
};

这是我想出的一个解决方案:

std::ostream& operator<< (std::ostream& out, const ReplayFrame& frame)
{
    out.write((char *) &frame.dataType_, sizeof(int));
    out.write((char *) &frame.timeStamp_, sizeof(int));
    out.write((char *) &frame.frameNumber_, sizeof(int));
    out.write((char *) &frame.dataSize_, sizeof(size_t));
    out.write(frame.data_, frame.dataSize_);

    return out;
}

这对我来说似乎很好,但它在某种程度上改变了 std::ostream& ReplayFrame::serialize(std::ostream& out, const ReplayFrame& frame) 这样的东西会更好?

或者我应该有一个serialize() 方法,它不使用流,而是返回大小和指向序列化对象的指针,然后我自己编写,例如:

ReplayFrame replayFrame;
int size;

char *frameSerialized = replayFrame.serialize(size);
fileStream.write(frameSerialized, size);

delete frameSerialized; // or frameSerialized.release() ?

如您所见,我很困惑,所以我愿意接受任何好的建议。 (注意:我使用的是 Qt,没有 boost,也没有 c++11)。

【问题讨论】:

  • 我认为,&lt;&lt; + ostream 保留用于文本表示。对于序列化,我可能只使用serialize 方法。
  • 你也许不应该依赖sizeof,因为有一天你的类可能会更改为包含动态分配的内存(例如,std::string

标签: c++ serialization operator-overloading class-design iostream


【解决方案1】:

首先重要的事情:只是将二进制数据转储到任何地方,无论是文件、另一个进程还是任何一个坏主意。您总是想要格式化数据,尽管格式可以是二进制的,并且可能与您当前正在开发的系统的内部表示相匹配。但是,您应该意识到,任何勉强成功的程序都将比不同的编译器世代更长寿,可能是处理器升级,并被移植到另一个平台。如果您的二进制格式取决于编译器现在如何表示数据,那么所有这些都会令人头疼。如果程序最终成功,那将是一个更大的麻烦。

你要注意的二进制格式的方面是

  • 单个单词的大小
  • 字中字节的顺序
  • 单词之间的潜在填充​​li>
  • 写入数据项的顺序

例如,仅使用sizeof() 来确定转储或读取的字节数在 32 位和 64 位平台之间不起作用。仅仅按照它们来的顺序转储字节是行不通的,例如,在 PowerPC 和 x86 系统之间。现在只是转储字节可能很容易,但在中期它会产生更多问题。

重载输出操作符是可以的,只要你不要使用带有这个操作符的文本格式的流类!您可以使用std::streambuf 层,它与读取和写入字节有关,例如,std::filebuf 来读取或写入文件,但是对于二进制格式的流,您需要在重载时使用专用的二进制流系统operator&lt;&lt;() .当然,这意味着类需要重载相应的操作才能在这个序列化系统中工作,但是混合文本和二进制格式的想法几乎肯定会引起很多麻烦。

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 2012-09-19
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    相关资源
    最近更新 更多