c++ - 从 streambuf 派生而不重写相应的流

标签 c++ stream fstream mmap streambuf

几天前,我决定编写一个使用mmap 和预读的streambuf 子类会很有趣。 我查看了我的 STL (SGI) 如何实现 filebuf 并意识到 basic_filebuf 包含一个 FILE*。所以从 basic_filebuf 继承是不可能的。

所以我继承自basic_streambuf。然后我想将我的 mmapbuf 绑定(bind)到一个 fstream。

我认为我唯一要做的就是复制 filebuf 的隐式接口(interface)...但这是一个明显的错误。在 SGI 中,basic_fstream 拥有一个 basic_filebuf。无论我是否调用 basic_filestream.std:::::ios::rdbuf( streambuf* ),文件流都会完全忽略它并使用它自己的 filebuf

所以现在我有点困惑...当然,我可以创建自己的 mmfstream,这将是 fstream 的精确复制/粘贴,但是听起来真的不是面向 DRY。

我不明白的是:为什么 fstreamfilebuf 如此紧密地结合在一起,以至于除了filebuf? 将流和缓冲区分开的全部意义在于可以使用具有不同缓冲区的流。

解决方案:

=> filestream 应该依赖于filebuf 的隐式接口(interface)。也就是说,fstream 应该由 streambuf 类模板化。这将允许每个人向 fstream 提供自己的 streambuf 子类,只要它实现了 filebuf 的隐式接口(interface)。问题:我们不能将模板参数添加到 fstream,因为它会在使用 fstream 作为模板模板参数时破坏模板选择器。

=> filebuf 应该是一个没有任何附加属性的纯虚类。这样就可以从它继承而无需携带它的所有 FILE* 垃圾。

你对这个主题的看法?

最佳答案

在 IO 流的设计中,大多数实际流的功能(相对于流缓冲区的功能)是在 std::basic_istream 中实现的,std::basic_ostream,以及它们的基类。 字符串和文件流类或多或少只是方便的包装器,可确保实例化具有正确缓冲区类型的流

如果您想扩展流,您几乎总是想提供您自己的流缓冲区类,而且您几乎永远不需要提供自己的流类。 .

一旦你有了自己的流缓冲区类型,你就可以将它作为你碰巧拥有的任何流对象的缓冲区。或者您从 std::basic_istreamstd::basic_ostreamstd::basic_iostream 派生您自己的类,它们实例化您的流缓冲区并通过它到他们的基类。
后者对用户来说更方便,但需要您为缓冲区的实例化编写一些样板代码(即流类的构造函数)。

回答您的问题:文件流和文件缓冲区耦合得如此紧密,因为前者的存在只是为了简化后者的创建。使用文件流可以轻松进行所有设置。
使用您自己的流类来包装您自己的流缓冲区的构造应该不是问题,因为无论如何您都不应该传递文件流,而只是(引用)基类。

关于c++ - 从 streambuf 派生而不重写相应的流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2989537/

相关文章:

c# - 在 Windows 应用商店应用程序中使用自定义流

c++ - cmd 窗口停止工作,文本文件被 fstream 读取错误

c++ - 拆分一串制表符分隔的整数并将它们存储在 vector 中

c++ - strtod 在同一变量上没有给出一致的结果?

c++ - 是否有实现条件累加的boost或STL函数?

c++ - 没有匹配的函数要调用:错误:必须使用 ‘.*’或 ‘->*’来调用 ‘f (…)’中的指针成员函数,例如 ‘(… ->* f) (…)’

c# - 使用 MemoryStream 模拟 NetworkStream 以进行单元测试

c++ - C++ 编译器可以缓存 constexpr 函数的结果吗?

java - 在 Servlet 端使用 excel 表生成内存中的 zip 文件

c++ - C++读写二进制文件