簡體   English   中英

從streambuf派生而不重寫相應的流

[英]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的。

我無法理解的是: 為什么fstreamfilebuf緊密結合,因此除了filebuf之外不可能使用其他任何東西? 分離流和bufs的關鍵在於可以使用具有不同緩沖區的流。

解決方案:

=> filestream應該依賴於filebuf的隱式接口。 也就是說,fstream應該由streambuf類進行模板化。 只要它實現了filebuf的隱式接口,這將允許每個人為fstream提供自己的streambuf子類。 問題:我們無法向fstream添加模板參數,因為它會在使用fstream作為模板模板參數時破壞模板選擇器。

=> filebuf應該是一個沒有任何附加屬性的純虛擬類。 這樣一個人就可以從中繼承而不攜帶所有的FILE *垃圾。

你對這個問題的想法?

在IO流的設計中,大多數實際流的功能(與流緩沖區的功能相反)是在std::basic_istreamstd::basic_ostream及其基類中實現的。 字符串和文件流類或多或少只是便利包裝器,它確保實例化具有正確類型緩沖區的流

如果要擴展流, 您幾乎總是希望提供自己的流緩沖類 ,並且幾乎不需要提供自己的流類。

一旦擁有了自己的流緩沖區類型,就可以使它成為您碰巧遇到的任何流對象的緩沖區。 或者從std::basic_istreamstd::basic_ostreamstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM