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