Сериализация C ++: перегрузка оператора вставки с помощью write ()

У меня есть простой класс, который содержит динамически распределенный массив, и мне нужно сериализовать его, чтобы он мог храниться в двоичном файле. Из-за массива я не могу использовать 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, без повышения и без C ++ 11).

2

Решение

Сначала важные вещи: просто выгрузка двоичных данных куда угодно, будь то файл, другой процесс или что-то плохое. Вы всегда хочу формат данные, хотя формат может быть двоичным, и он может соответствовать аспектам внутреннего представления системы, в которой вы в настоящее время разрабатываете. Однако вы должны понимать, что любая незначительно успешная программа переживет разные поколения компиляторов, возможно, обновления процессора, и будет перенесена на другую платформу. Если ваш двоичный формат зависит от того, как компилятор сейчас представляет данные, то все это будет головной болью. Если программа закончится успешно, это будет еще большей головной болью.

Аспекты двоичного формата, на которые вы хотите обратить внимание:

  • размер отдельных слов
  • порядок байтов в словах
  • потенциальное заполнение между словами
  • порядок написания элементов данных

Просто используя, например, sizeof() определить, сколько байтов сброшено или считано, не работает между 32-битными и 64-битными платформами. Простой вывод байтов в порядке их поступления не работает, например, между системами PowerPC и x86. Просто выгрузка байтов может быть легкой, но в среднесрочной перспективе это создаст больше проблем.

Перегрузка выходных операторов в порядке, если вы не используйте текстовые отформатированные потоковые классы с этими операторами! Вы можете использовать std::streambuf слой, который занимается чтением и записью байтов, например, std::filebuf читать из файла или записывать в него, но для двоичного потока, который вы хотите, выделите систему двоичных потоков при перегрузке operator<<(), Конечно, это означает, что классы должны будут перегружать соответствующие операции для работы в этой системе сериализации, но смешивание текста и двоичного формата почти наверняка вызовет много горя.

1

Другие решения

Других решений пока нет …