我的实现overflow()有什么问题? [英] What is wrong with my implementation of overflow()?

查看:179
本文介绍了我的实现overflow()有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个流缓冲区,我有麻烦使 overflow()工作。我调整缓冲区10个字符,并使用 setp 重置缓冲区。然后我将指针增加回我们离开的地方。由于某种原因,输出不正确:

I am trying to implement a stream buffer and I'm having trouble with making overflow() work. I resize the buffer by 10 more characters and reset the buffer using setp. Then I increment the pointer back where we left off. For some reason the output is not right:

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();
}

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

When I print the string it comes out as:


hello worl How are ou?

hello worl how are ou?

c $ c> d 和 y

It's missing the d and the y. What did I do wrong?

推荐答案

第一件事不是你是从 std派生的: :basic_stringbuf< char> ,而不覆盖所有相关的虚拟函数。例如,你不重写 xsputn() sync():无论这些函数最终会做什么' ll继承。我强烈建议改为从 std :: basic_streambuf< char> 派生流缓冲区!

The first thing to not is that you are deriving from std::basic_stringbuf<char> for whatever reason without overriding all of the relevant virtual functions. For example, you don't override xsputn() or sync(): whatever these functions end up doing you'll inherit. I'd strongly recommend to derive your stream buffer from std::basic_streambuf<char> instead!

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

The overflow() method announces a buffer which is one character smaller than the string to the stream buffer: &buffer.back() isn't a pointer to the end of the array but to the last character in the string. Personally, I would use

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

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

There is no problem so far. However, after making space for more characters you omitted adding the overflowing character, i.e., the argument passed to overflow() to the buffer:

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

还有一些不太对的事情:

There are a few more little things which are not quite right:


  1. virtual 函数替换为默认参数通常是个坏主意。

  2. 返回的字符串可能包含多个空字符结束,因为保持的字符串实际上比写入到目前为止的序列大,除非缓冲区完全满。您应该可以不同地实现 str()函数:

  1. It is generally a bad idea to give overriding virtual functions a default parameter. The base class function already provides the default and the new default is only picked up when the function is ever called explicitly.
  2. The string returned may contain a number of null characters at the end because the held string is actually bigger than sequence which was written so far unless the buffer is exactly full. You should probably implement the str() function differently:

std::basic_string<charT> str() const
{
    return this->buffer.substr(0, this->pptr() - this->pbase());
}


  • 以常数值增长字符串是一个主要的性能问题:写 n 个字符是 n * n 。对于更大的 n (他们真的不需要变得巨大),这将导致问题。你会以指数方式增长缓冲区,例如每次增加一倍或增加一个 1.5 if你觉得加倍并不是一个好主意。

  • Growing the string by a constant value is a major performance problem: the cost of writing n characters is n * n. For larger n (they don't really need to become huge) this will cause problems. You are much better off growing your buffer exponentially, e.g., doubling it every time or growing by a factor of 1.5 if you feel doubling isn't a good idea.
  • 这篇关于我的实现overflow()有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆