Как мне создать свой собственный ostream / streambuf? - PullRequest
22 голосов
/ 08 февраля 2009

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

  1. исправление порядка байтов при выполнении << myVar; </li>
  2. хранить в контейнере deque вместо использования std: cout или записи в файл
  3. регистрировать дополнительные данные, такие как, сколько раз я сделал <<, сколько раз я сделал .write, количество записанных байт и сколько раз я сбрасывал (). Но мне не нужна вся информация. </li>

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

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

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

Ответы [ 3 ]

24 голосов
/ 09 февраля 2009

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

6 голосов
/ 28 августа 2009

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

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

  • переполнение (поместите один символ или буфер очистки) ( ссылка )
  • xsputn (поместить массив символов в буфер) ( ссылка )
  • синхронизация ( ссылка )
1 голос
/ 09 февраля 2009

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

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

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

...