[英]Deriving from streambuf without rewriting a corresponding stream
幾天前,我決定編寫一個使用mmap
和預讀的streambuf
子類會很有趣。 我看了一下我的STL(SGI)如何實現filebuf
並意識到basic_filebuf
包含一個FILE*
。 所以從basic_filebuf
繼承是basic_filebuf
的。
所以我繼承了basic_streambuf
。 然后我想將我的mmapbuf
綁定到fstream。
我認為我唯一需要做的就是復制filebuf
的隱式接口......但這是一個明顯的錯誤。 在SGI中, basic_fstream
擁有basic_filebuf
。 無論我是否調用basic_filestream.std::::ios::rdbuf( streambuf* )
,文件流都會完全忽略它並使用自己的filebuf
。
所以現在我有點困惑......當然,我可以創建自己的mmfstream
,這將是fstream
的精確復制/粘貼,但聽起來確實不是面向DRY的。
我無法理解的是: 為什么fstream
與filebuf
緊密結合,因此除了filebuf
之外不可能使用其他任何東西? 分離流和bufs的關鍵在於可以使用具有不同緩沖區的流。
解決方案:
=> filestream
應該依賴於filebuf
的隱式接口。 也就是說,fstream應該由streambuf類進行模板化。 只要它實現了filebuf
的隱式接口,這將允許每個人為fstream
提供自己的streambuf子類。 問題:我們無法向fstream
添加模板參數,因為它會在使用fstream
作為模板模板參數時破壞模板選擇器。
=> filebuf
應該是一個沒有任何附加屬性的純虛擬類。 這樣一個人就可以從中繼承而不攜帶所有的FILE *垃圾。
你對這個問題的想法?
在IO流的設計中,大多數實際流的功能(與流緩沖區的功能相反)是在std::basic_istream
, std::basic_ostream
及其基類中實現的。 字符串和文件流類或多或少只是便利包裝器,它確保實例化具有正確類型緩沖區的流 。
如果要擴展流, 您幾乎總是希望提供自己的流緩沖類 ,並且幾乎不需要提供自己的流類。 。
一旦擁有了自己的流緩沖區類型,就可以使它成為您碰巧遇到的任何流對象的緩沖區。 或者從std::basic_istream
, std::basic_ostream
和std::basic_iostream
std::basic_ostream
自己的類,它實例化您的流緩沖區並將其傳遞給它們的基類。
后者對用戶來說更方便,但是需要你為緩沖區的實例化編寫一些樣板代碼(即流類的構造函數)。
回答你的問題:文件流和文件緩沖區的連接非常緊密,因為前者僅用於簡化后者的創建。 使用文件流可以輕松設置所有內容。
使用您自己的流類來包裝自己的流緩沖區的構造應該不是問題,因為您不應該傳遞文件流,而只是(引用)基類。
fstream
本身並不是一個大課程。 它繼承自basic_stream
以提供對所有<<
和>>
操作的支持,包含必須初始化的專用steambuf
,以及將參數傳遞給streambuf
構造函數的相應構造函數。
從某種意義上說,你寫的有關模板化解決方案的內容是可以的。 但是basic_stream
也可以導出到例如tcp_stream
中。 在那種情況下, fstream
的構造函數有點無用。 因此,您需要提供一個新的tcpstream
類,繼承自basic_stream
,並為構造函數提供正確的參數,以便能夠創建tcp_stream
。 最后,你不會使用fstream
任何內容。 創建這個新的tcpstream
只需編寫3或4個函數。
最后,您將從fstream
類派生而沒有任何真正的理由。 這將在類層次結構中添加更多耦合,不需要耦合。
查看Boost.Iostreams庫中的mapped_file 。 我自己從未使用過它,但它似乎已經可以做你需要的了。
編輯:糟糕,重讀你的問題,我看到你這樣做是為了好玩。 也許你可以從Boost.Iostreams中汲取靈感?
整點std::fstream
是,它是一個_˚F_ile基礎std::stream
。 如果你想要一個mmstreambuf
支持的普通std::stream
,你應該創建一個mmstreambuf
並將它傳遞給std::stream::stream(std::streambuf*)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.