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

19

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

  1. фиксируют конечные элементы при выполнении & lt; & lt; MYVAR;
  2. хранить в контейнере deque вместо использования std: cout или записи в файл
  3. записывать дополнительные данные, например, сколько раз я делал & lt; & lt ;, сколько раз я делал .write, количество байтов, которые я написал, и сколько раз я сбрасывал (). Но мне не нужна вся информация.

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

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

в моем классе basic_stringstream2 (я скопировал paste basic_stringstream в мой файл cpp и изменил его), но код продолжал использовать basic_ostream. Я просмотрел код, и мне кажется, что мне нужно перегрузить xsputn (что не упоминается на этой странице Ссылка ) но что еще мне нужно для перегрузки? и как я могу построить свой класс (что ему нужно для наследования и т. д.)?

    
задан greatwolf 07.02.2009 в 22:45
источник
  • Не могли бы вы предоставить отрывок из кода, который «использовался с использованием basic_ostream»? –  Paolo Tedesco 09.02.2009 в 09:45

3 ответа

24

Канонический подход состоит в определении вашего собственного streambuf. Вы должны посмотреть:

ответ дан Luc Hermitte 09.02.2009 в 16:39
6

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

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

  • переполнение (поместите один буфер char или flush) ( ссылка )
  • xsputn (помещает массив символов в буфер) ( ссылка )
  • sync ( ссылка )
ответ дан mandrake 28.08.2009 в 09:07
  • Большинство ссылок в этом теперь свисают. –  Omnifarious 20.10.2017 в 02:59
1

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

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

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

    
ответ дан Sol 09.02.2009 в 15:55