Как создать свой собственный ostream / streambuf?

для образовательных целей я хочу создать буфер ostream и stream, чтобы сделать:

  1. исправить endians при выполнении
  2. хранить в контейнере deque вместо использования std: cout или записи в файл
  3. войти дополнительные данные, например, сколько раз я сделал

Я попытался перегрузить, но потерпел ужасную неудачу. Я пробовал перегружать запись, делая

ostream& write( const char* s, streamsize n ) 

в моем классе basic_stringstream2 (я скопировал вставить basic_stringstream в мой файл cpp и изменил его), но код продолжал использовать basic_ostream. Я просмотрел код, и похоже, мне нужно перегрузить xsputn (который не упоминается на этой странице http://www.cplusplus.com/reference/iostream/ostream) но что еще мне нужно перегрузить? и как я могу построить свой класс (что ему нужно наследовать и т. д.)?

3 ответов


канонический подход заключается в определении собственного streambuf. Вы должны взглянуть на:


для A+C) я думаю, вы должны смотреть на грани, они изменяют, как объекты записываются как символы. Здесь вы также можете хранить статистику о том, сколько раз вы транслировали свои объекты. Проверьте как форматировать мои собственные объекты при использовании потоков STL? для примера.

для B) вам нужно создать свой собственный streambuf и подключить свой ostream к этому буферу (аргумент конструктора). См.Люк + получение новых классов streambuf. В короче вам нужно реализовать это для ostream (минимум):

  • переполнение (поместите один символ или флеш-буфер) (ссылке)
  • xsputn (поместите массив символов в буфер) (ссылке)
  • синхронизации (ссылке)

Я не уверен, что то, что вы хотите сделать, это возможно. The << операторы не виртуальный. Так можно определить yourstream &operator << (yourstream &strm, int i) делать то, что вы хотите с endian преобразования и подсчета, и он будет работать, когда ваш код вызывает его напрямую. Но если вы передаете объект yourstream в функцию, которая ожидает ostream, в любое время, когда эта функция вызывает <<, он перейдет в исходную версию ostream вместо вашей.

как я понимаю, объекты streams были установлены так что вы можете "легко" определить новый тип потока, который использует другой вид буфера (например, Деку символов), и вы можете очень легко добавить поддержку вывода ваших собственных классов через <<. Я не думаю, что вы должны быть в состоянии переопределить средний слой между ними.

и особенно, весь смысл << интерфейс должен обеспечить красиво отформатированный текстовый вывод, в то время как звучит так, как будто вы действительно хотите двоичный вывод. (В противном случае ссылка на "прямой" не имеет смысла.) Даже если предположить, что есть какой-то способ сделать это, я не знаю, это приведет к неудобному двоичному выходу в лучшем случае. Например, рассмотрим перегрузку конечного пользователя для вывода точки в 3D-пространстве. Версия конечного пользователя << вероятно, сделать что-то вроде << '(' << x << ", " << y << ", " << z << ')'. Это будет хорошо выглядеть в текстовом потоке, но это много потерянных и совершенно бесполезных символов в двоичном потоке, который в идеале просто использует << x << y << z. (И сколько звонков в << если они считаются как?)