【问题标题】:Which buffer should be set by basic_streambuf::setbuf?basic_streambuf::setbuf 应该设置哪个缓冲区?
【发布时间】:2011-11-15 22:58:10
【问题描述】:
我正在使用basic_streambuf 来处理从/向 Winsock 套接字读取和写入的问题。就像basic_filebuf 一样,我在内部使用std::codecvt 对象将从底层套接字读取的字节转换为“套接字流缓冲区”的字符类型,并将写入套接字流缓冲区的字符转换为可以写入的字节到底层套接字。为了做到这一点,我发现我需要为 streambuf 的读取和写入功能维护缓冲区。
我遇到的逻辑问题是streambuf 实现旨在用于读取和写入(std::iostream constructor 采用单个指向streambuf 的指针),但只有一个可覆盖的成员函数可以自定义设置底层字符缓冲区:setbuf。如果我想允许我的套接字流缓冲模板的用户设置底层缓冲区,setbuf 应该设置读取缓冲区还是写入缓冲区?哪个选项更有意义?
【问题讨论】:
标签:
c++
io
winsock
streambuf
【解决方案1】:
std::iostream 继承自 std::istream 和 std::ostream,但那些实际上都继承自包含缓冲区的 std::ios。由于它们实际上都继承自std::ios,因此std::iostream 的基址只有一个std::ios,因此只有一个内部缓冲区。
来自 C++11 Feb 2011 草案:
§ 27.6.3
类模板 basic_streambuf 作为一个抽象基类,用于派生各种
每个对象控制两个字符序列的流缓冲区:
— 字符输入序列;
— 一个字符输出序列。
§ 27.7.2
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_istream : virtual public basic_ios<charT,traits> {
§ 27.7.3
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ostream : virtual public basic_ios<charT,traits> {
【解决方案2】:
标准流只有两个通过 setbuf 指定的行为。第一个是 setbuf(0,0) 可能没有效果,第二个是 basic_filebuf,如果 setbuf(0,0) 在任何 IO 之前调用,则 IO 是无缓冲的。否则,结果由实现定义。所以只要做对你的实施有意义的事情,然后记录下来。