Вытекает из StreamBuf, не переписывая соответствующий поток

StackOverflow https://stackoverflow.com/questions/2989537

Вопрос

Несколько дней назад я решил, что было бы весело написать streambuf Подкласс, который использовал бы mmap и читать. Я посмотрел, как реализован мой STL (SGI) filebuf и понял это basic_filebuf содержит FILE*. Анкет Так что наследуя от basic_filebuf не может быть и речи.

Так что я унаследовал от basic_streambuf. Анкет Тогда я хотел связать свой mmapbuf к FSTREAM.

Я думал, что единственное, что мне нужно было сделать, это скопировать неявный интерфейс filebuf... но это была явная ошибка. В SGI, basic_fstream владеет basic_filebuf. Анкет Неважно, звоню ли я basic_filestream.std::::ios::rdbuf( streambuf* ), FileStream полностью игнорирует его и использует свой собственный filebuf.

Так что теперь я немного смущен ... конечно, я могу создать свой собственный mmfstream, это была бы точная копия/вставка fstream Но это звучит действительно не сухой.

Чего я не могу понять, так это: Почему fstream так тесно связан с filebuf, так что невозможно использовать ничего другого, кроме filebuf? Весь смысл разделения потоков и BUFS заключается в том, что можно использовать поток с другим буфером.

Решения:

=> filestream должен полагаться на неявный интерфейс filebuf. Анкет То есть FSTREAM должен быть шаблон классом StreamBuf. Это позволило бы каждому предоставить свой собственный подкласс Streambuf для fstream Пока он реализует filebufнеявный интерфейс. Проблема: мы не можем добавить параметр шаблона в fstream Поскольку это сломало бы селекторы шаблонов при использовании fstream как шаблон шаблона.

=> filebuf должен быть чистым виртуальным классом без каких -либо дополнительных атрибутов. Так что можно унаследовать от него, не неся весь свой файл* мусор.

Ваши идеи на эту тему?

Это было полезно?

Решение

Проверить mappen_file в Boost.iostreams библиотека. Я никогда не использовал его сам, но кажется, что это уже может сделать то, что вам нужно.

РЕДАКТИРОВАТЬ: Ой, перечитывайте ваши вопросы, и я вижу, что вы делаете это для развлечения. Возможно, вы можете черпать вдохновение из Boost.iostreams?

Другие советы

В дизайне IO Streams «Функциональность фактических потоков» (в отличие от функциональности буферов потока) реализована в std::basic_istream, std::basic_ostream, и их базовые классы. Классы потока строки и файлов более или менее просто удобные обертки, которые обеспечивают создание потока с правильным типом буфера.

Если вы хотите расширить потоки, Вы почти всегда хотите предоставить свой собственный класс буфера потока, И вам почти никогда не нужно предоставлять свой собственный класс потока. Анкет

После того, как у вас есть собственный тип буфера потока, вы можете сделать его буфером для любого объекта потока, который у вас есть. Или вы получаете свои собственные занятия из std::basic_istream, std::basic_ostream, а также std::basic_iostream который создает экземпляр вашего буфера потока и передает его базовым классам.
Последнее удобнее для пользователей, но требует, чтобы вы написали код котла для создания экземпляра буфера (а именно конструкторы для класса потока).

Чтобы ответить на ваш вопрос: потоки файлов и файловый буфер связаны так тесно, потому что первый существует только для облегчения создания последнего. Использование потока файла позволяет легко установить все это.
Использование собственного класса потока для обертывания конструкции вашего собственного буфера потока не должно быть проблемой, так как вам в любом случае не следует передавать потоки файлов, но только (ссылки) базовым классам.

fstream само по себе не большой класс. Это наследует от basic_stream Чтобы обеспечить поддержку всем << а также >> операции содержит специализированные steambuf которые должны быть инициализированы, и соответствующие конструкторы для передачи параметров в streambuf конструктор.

В некотором смысле, что вы написали о своем шаблонном решении, в порядке. Но basic_stream также может быть получен в tcp_stream Например. В этом случае конструкторы fstream немного бесполезны. Таким образом, вам нужно предоставить новый tcpstream класс, наследуя от basic_stream с правильными параметрами для конструкторов, чтобы иметь возможность создавать tcp_stream. Анкет В конце концов, вы ничего не будете использовать от fstream. Анкет Создание этого нового tcpstream это вопрос написания 3 или 4 функций.

В конце концов, вы получите из fstream класс без какой -либо реальной причины. Это добавило бы больше связи в классовой иерархии, ненужную связь.

Весь смысл std::fstream это то, что это _Фланг_ile на основе std::stream. Анкет Если вы хотите обычного std::stream при поддержке вашего mmstreambuf, тогда вы должны создать mmstreambuf и передать это std::stream::stream(std::streambuf*)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top