Как создать свой собственный ostream / streambuf?
для образовательных целей я хочу создать буфер ostream и stream, чтобы сделать:
- исправить endians при выполнении
- хранить в контейнере deque вместо использования std: cout или записи в файл
- войти дополнительные данные, например, сколько раз я сделал
Я попытался перегрузить, но потерпел ужасную неудачу. Я пробовал перегружать запись, делая
ostream& write( const char* s, streamsize n )
в моем классе basic_stringstream2 (я скопировал вставить basic_stringstream в мой файл cpp и изменил его), но код продолжал использовать basic_ostream. Я просмотрел код, и похоже, мне нужно перегрузить xsputn (который не упоминается на этой странице http://www.cplusplus.com/reference/iostream/ostream) но что еще мне нужно перегрузить? и как я могу построить свой класс (что ему нужно наследовать и т. д.)?
3 ответов
канонический подход заключается в определении собственного streambuf. Вы должны взглянуть на:
- статьи Анжелики Лангер о выводе IOStreams
- статьи Джеймса Канзе о фильтрации streambufs
- импульс.библиотеки iostream примеры применения
для A+C) я думаю, вы должны смотреть на грани, они изменяют, как объекты записываются как символы. Здесь вы также можете хранить статистику о том, сколько раз вы транслировали свои объекты. Проверьте как форматировать мои собственные объекты при использовании потоков STL? для примера.
для B) вам нужно создать свой собственный streambuf и подключить свой ostream к этому буферу (аргумент конструктора). См.Люк + получение новых классов streambuf. В короче вам нужно реализовать это для ostream (минимум):
Я не уверен, что то, что вы хотите сделать, это возможно. The <<
операторы не виртуальный. Так можно определить yourstream &operator << (yourstream &strm, int i)
делать то, что вы хотите с endian преобразования и подсчета, и он будет работать, когда ваш код вызывает его напрямую. Но если вы передаете объект yourstream в функцию, которая ожидает ostream, в любое время, когда эта функция вызывает <<
, он перейдет в исходную версию ostream вместо вашей.
как я понимаю, объекты streams были установлены так что вы можете "легко" определить новый тип потока, который использует другой вид буфера (например, Деку символов), и вы можете очень легко добавить поддержку вывода ваших собственных классов через <<
. Я не думаю, что вы должны быть в состоянии переопределить средний слой между ними.
и особенно, весь смысл <<
интерфейс должен обеспечить красиво отформатированный текстовый вывод, в то время как звучит так, как будто вы действительно хотите двоичный вывод. (В противном случае ссылка на "прямой" не имеет смысла.) Даже если предположить, что есть какой-то способ сделать это, я не знаю, это приведет к неудобному двоичному выходу в лучшем случае. Например, рассмотрим перегрузку конечного пользователя для вывода точки в 3D-пространстве. Версия конечного пользователя <<
вероятно, сделать что-то вроде << '(' << x << ", " << y << ", " << z << ')'
. Это будет хорошо выглядеть в текстовом потоке, но это много потерянных и совершенно бесполезных символов в двоичном потоке, который в идеале просто использует << x << y << z
. (И сколько звонков в <<
если они считаются как?)