Я придумал лучший дизайн для двоичного ввода / вывода. Фундаментальный подход состоит в том, чтобы иметь три метода: size_on_stream, load_from_buffer,
и store_to_buffer
. Они входят в интерфейсный класс, так что все классы, которые поддерживают бинарный ввод / вывод, наследуют его.
Метод size_on_stream
возвращает размер данных, передаваемых в потоке. Как правило, это не включает байты заполнения. Это должно быть рекурсивным, чтобы класс вызывал метод для всех своих членов.
Методу load_from_buffer
передается ссылка на указатель на буфер ( unsigned char * &
). Метод загружает элементы данных объекта из буфера, увеличивая указатель после каждого элемента (или увеличивая один раз после всех элементов).
Метод store_to_buffer
сохраняет данные в заданном буфере и увеличивает указатель.
Клиент вызывает size_on_stream
, чтобы определить размер всех данных. Буфер такого размера выделяется динамически. Другой указатель на этот буфер передается в store_to_buffer
для сохранения членов объекта в буфере. Наконец, клиент использует двоичную запись (fwrite or std::ostream::write)
для передачи буфера в поток.
Некоторые из преимуществ этого метода: упаковка, абстракция и блок ввода / вывода. Объекты упаковывают свои элементы в буфер. Процесс записи в буфер скрыт от клиента. Клиент может использовать функции блочного ввода-вывода, которые всегда более эффективны, чем передача отдельных членов.
Этот дизайн также более переносим, поскольку объекты могут заботиться о Endianess. Для этого есть простой метод, который оставлен на усмотрение читателя.
Я расширил эту концепцию, включив в нее также типы POD (Plain Old Data), что оставлено для читателя в качестве упражнения.