从StreamBuf派生而无需重写相应的流
题
几天前,我决定写一个很有趣的 streambuf
将使用的子类 mmap
和读书。我查看了我的STL(SGI)的实施方式 filebuf
并意识到这一点 basic_filebuf
包含a FILE*
. 。因此继承 basic_filebuf
是不可能的。
所以我继承了 basic_streambuf
. 。那我想约束我的 mmapbuf
到Fstream。
我认为我唯一要做的就是复制 filebuf
...但这是一个明显的错误。在SGI中, basic_fstream
拥有a basic_filebuf
. 。不管我打电话 basic_filestream.std::::ios::rdbuf( streambuf* )
, ,文件流完全忽略并使用自己的 filebuf
.
所以现在我有点困惑...当然,我可以创建自己的 mmfstream
, ,那将是 fstream
但这听起来确实不是干燥的。
我听不懂的是: 为什么 fstream
如此紧密地与 filebuf
, ,因此除了 filebuf
? 分离流和BUF的全部要点是,可以使用带有不同缓冲区的流。
解决方案:
=> filestream
应该依靠 filebuf
. 。也就是说,Fstream应通过StreamBuf类模板。这将使每个人都能提供自己的StreamBuf子类 fstream
只要实施 filebuf
的隐式接口。问题:我们不能将模板参数添加到 fstream
因为它会在使用时打破模板选择器 fstream
作为模板模板参数。
=> filebuf
应该是一个纯虚拟类,而没有任何其他属性。因此,一个人可以从中继承它,而无需携带所有文件*垃圾。
您对这个主题的想法?
解决方案
查看 mapped_file 在里面 boost.iosstreams 图书馆。我从来没有自己使用过它,但是看来它可能已经完成了您需要的事情。
编辑:糟糕,重新阅读您的问题,我看到您是为了好玩的。也许您可以从boost.iostreams中汲取灵感?
其他提示
在IO流的设计中,大多数实际流的功能(与流缓冲区功能相反)在 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
是_F_基于 std::stream
. 。如果你想要一个普通的 std::stream
由你的支持 mmstreambuf
, ,那么您应该创建一个 mmstreambuf
并将其传递给 std::stream::stream(std::streambuf*)