gpt4 book ai didi

c++ - 如果您不在派生类实现中这样做, `basic_streambuf` 是否会创建自己的获取/放置区域?

转载 作者:太空狗 更新时间:2023-10-29 21:34:02 24 4
gpt4 key购买 nike

我已经多次看到有关创建自定义流缓冲区的说明:您需要做的就是实现 overflow , underflow , 和 pbackfail正确地在 std::basic_streambuf 的后代中您可以创建一个使用它格式化数据的流。这三个例程定义了自定义流的“受控序列”。

但是std::basic_streambuf的 protected 成员列表中还有其他的怪物潜伏着, 即 setgsetp .这些为输入和输出设置缓冲区。获取和设置数据的公共(public)成员在遵循受控序列之前首先尝试访问这些区域。

对于几个不同的自定义流缓冲区,如果流设置自己的获取/放置区域,则可能会出现问题。所以我希望这样的 streambufs 避免使用 get/put 区域并且总是使用overflow , underflow , 和 pbackfail没有任何中间缓冲。

对于一个天真的简化示例,如果您正在包装另一个 streambuf 的实现 underflow可能看起来像这样:

template <class C, class TR>
typename TR::int_type wrapping_streambuf<C, TR>::underflow()
{
return m_wrapped_streambuf->sgetc();
}

让包装的 streambuf 处理所有脏工作。这是另一个用于计算行数的简单示例:

template <class C, class TR>
typename TR::int_type tracking_streambuf<C, TR>::uflow()
{
auto rv = m_wrapped_streambuf->sbumpc();
if (rv == (TR::int_type)'\n') ++ m_input_line_count;
return rv;
}

对于这样的流,setg 没有有用的实现因为您无法访问包装缓冲区的内部获取区域。对于 tracked_streambuf , 获取/放置区域的强加将使计数线与流的逻辑顺序同步是不可能的。

我认为答案是永远不要调用 setgsetp在后代中。事实上,他们可能应该覆盖 setg , setp , gbump , 和 pbump抛出异常。

查看 <streambuf> header 我看到一个自定义的 streambuf 如果我这样做,在我最喜欢的库实现中可能会按我想要的方式工作(有空 gptr/pptr 检查)。但这是保证吗?

最佳答案

std::basic_streambuf 的默认构造函数将定义 get 和 put 区域的六个指针设置为空指针值,因此默认情况下它不会“创建自己的 get/put 区域”。

函数 setgsetpgbumppbump 是 protected 成员,不会被调用默认情况下公共(public)成员函数,所以你不必担心它们。当然,覆盖它们以抛出异常也不错。

此外,没有中间缓冲区的自定义流缓冲区类也应覆盖 uflow函数,它可以被公共(public)成员函数调用以处理溢出情况,其中 get 指针的值需要被提前。默认情况下,它的默认行为是(引自 [streambuf.virt.get]/16 ):

Default behavior: Calls underflow(). If underflow() returns traits​::​eof(), returns traits​::​eof(). Otherwise, returns the value of traits​::​to_­int_­type(*gptr()) and increment the value of the next pointer for the input sequence.

因此,如果您不覆盖此函数,它会导致通过空指针进行间接访问的未定义行为。

关于c++ - 如果您不在派生类实现中这样做, `basic_streambuf` 是否会创建自己的获取/放置区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48463767/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com