tem*_*boy 2 c++ streambuf c++11
我正在尝试实现一个流缓冲区,我在制作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();
}
Run Code Online (Sandbox Code Playgroud)
当我打印字符串时,它出现为:
你好,你好吗?
它错过了d和y.我做错了什么?
首先,不是std::basic_stringbuf<char>因为任何原因而不是覆盖所有相关的虚函数.例如,你不要覆盖xsputn()或sync():无论这些函数最终做什么,你都会继承.我强烈建议从中派生你的流缓冲区std::basic_streambuf<char>!
该overflow()方法宣布一个缓冲区,该缓冲区比流缓冲区的字符串小一个字符:&buffer.back()不是指向数组末尾但指向字符串中最后一个字符的指针.就个人而言,我会用
this->setp(&this->buffer.front(), &this->buffer.front() + this->buffer.size());
Run Code Online (Sandbox Code Playgroud)
到目前为止没有问题.但是,在为更多字符创建空间后,您省略了添加溢出字符,即传递给overflow()缓冲区的参数:
this->pbump(diff);
*this->pptr() = traits::to_char_type(c);
this->pbump(1);
Run Code Online (Sandbox Code Playgroud)
还有一些不太恰当的小事:
virtual函数作为默认参数通常是一个坏主意.基类函数已经提供了默认值,只有在显式调用函数时才会获取新的默认值.返回的字符串最后可能包含许多空字符,因为保持的字符串实际上大于目前为止写入的序列,除非缓冲区完全填满.你应该以str()不同的方式实现这个功能:
std::basic_string<charT> str() const
{
return this->buffer.substr(0, this->pptr() - this->pbase());
}
Run Code Online (Sandbox Code Playgroud)n字符的成本是n * n.对于更大的n(它们实际上不需要变大)这将导致问题.你最好不要buffer成倍地增长,例如,每次增加一倍,或者增加1.5一倍,如果你觉得加倍不是一个好主意.| 归档时间: |
|
| 查看次数: |
484 次 |
| 最近记录: |