2

我正在尝试实现一个流缓冲区,但我在overflow()工作时遇到了麻烦。我将缓冲区大小再调整 10 个字符并使用setp. 然后我将指针返回到我们离开的地方。由于某种原因,输出不正确:

template <class charT, class traits = std::char_traits<charT>>
class stringbuf : public std::basic_stringbuf<charT, traits>
{
public:
    using char_type   = charT;
    using traits_type = traits;
    using int_type    = typename traits::int_type;
public:
    stringbuf()
        : buffer(10, 0)
    {
        this->setp(&buffer.front(), &buffer.back());
    }

    int_type overflow(int_type c = traits::eof())
    {
        if (traits::eq_int_type(c, traits::eof()))
            return traits::not_eof(c);

        std::ptrdiff_t diff = this->pptr() - this->pbase();

        buffer.resize(buffer.size() + 10);
        this->setp(&buffer.front(), &buffer.back());

        this->pbump(diff);

        return traits::not_eof(traits::to_int_type(*this->pptr()));
    }
    // ...
    std::basic_string<charT> str()
    {
        return buffer;
    }
private:
    std::basic_string<charT> buffer;
};

int main()
{
    stringbuf<char> buf;
    std::ostream os(&buf);

    os << "hello world how are you?";
    std::cout << buf.str();
}

当我打印字符串时,它显示为:

你好,你好吗?

它缺少dy。我做错了什么?

4

1 回答 1

5

首先要注意的是,std::basic_stringbuf<char>无论出于何种原因,您都没有覆盖所有相关的虚函数。例如,您不会覆盖xsputn()sync():无论这些功能最终做什么,您都将继承。我强烈建议您从中派生流缓冲区std::basic_streambuf<char>

overflow()方法向流缓冲区宣布一个比字符串小一个字符的缓冲区:&buffer.back()不是指向数组末尾的指针,而是指向字符串中最后一个字符的指针。就个人而言,我会使用

this->setp(&this->buffer.front(), &this->buffer.front() + this->buffer.size());

到目前为止没有问题。但是,在为更多字符腾出空间后,您省略了添加溢出字符,即传递给overflow()缓冲区的参数:

this->pbump(diff);
*this->pptr() = traits::to_char_type(c);
this->pbump(1);

还有一些小事情不太对劲:

  1. 给覆盖virtual函数一个默认参数通常是一个坏主意。基类函数已经提供了默认值,并且只有在显式调用该函数时才会使用新的默认值。
  2. 返回的字符串末尾可能包含许多空字符,因为保存的字符串实际上大于到目前为止写入的序列,除非缓冲区完全满。您可能应该以str()不同的方式实现该功能:

    std::basic_string<charT> str() const
    {
        return this->buffer.substr(0, this->pptr() - this->pbase());
    }
    
  3. 将字符串增加一个常数值是一个主要的性能问题:写入n字符的成本是n * n. 对于更大的n(它们实际上并不需要变得很大),这将导致问题。你最好以buffer指数方式增长,例如,每次都加倍,或者1.5如果你觉得加倍不是一个好主意,则增长一个因素。
于 2013-11-08T00:18:07.830 回答