我正在尝试创建std :: stringbuf的自定义实现。在某些平台上它工作正常,而在其他平台上我得到意想不到的结果。这是我的班级和测试证明问题:
#include <iostream>
#include <vector>
#include <sstream>
class CombinedLogger : public std::ostream
{
public:
explicit CombinedLogger() : std::ostream(&buffer), buffer(*this) {}
virtual ~CombinedLogger() = default;
void Add(std::ostream& log)
{
logs.push_back(&log);
}
private:
class CombinedStreamBuffer : public std::stringbuf
{
public:
explicit CombinedStreamBuffer(CombinedLogger &log) : log(log) {}
virtual ~CombinedStreamBuffer() = default;
protected:
virtual int overflow(int c)
{
if (c != traits_type::eof())
{
someCustomBuffer << static_cast<char>(c);
}
return c;
}
virtual int sync()
{
for (auto& l : log.logs)
{
*l << someCustomBuffer.str();
l->flush();
}
someCustomBuffer.str("");
str("");
return 0;
}
private:
CombinedLogger &log;
std::stringstream someCustomBuffer;
} buffer;
std::vector<std::ostream*> logs;
};
int main(int, char*[])
{
CombinedLogger cl;
cl.Add(std::cout);
cl << "This is a test to see if my string gets chopped up" << std::endl;
cl << "Here's another test to see if my string gets chopped up" << std::endl;
cl << "And a third test to see if my string gets chopped up" << std::endl;
return 0;
}
当我在Windows下编译并运行时,我得到了我期望的输出:
This is a test to see if my string gets chopped up
Here's another test to see if my string gets chopped up
And a third test to see if my string gets chopped up
如果我在Ubuntu下编译并运行,输出看起来像这样:
This is a test to see if my string gets chopped up
test to see if my string gets chopped up
t to see if my string gets chopped up
经过一些调试和实验,我发现缺少的字符实际上最终出现在std :: stringbuf自己的内部缓冲区中(可通过str()访问)。如果我也覆盖xsputn(),我可以确定所有内容都放入我的客户缓冲区。我的问题是:为什么我必须这样做?我的理解是我不应该覆盖除overflow()之外的任何东西,因为我没有指定任何其他缓冲区(通过setp()),所以std :: stringbuf缓冲区的大小应该为零,并且应该调用overflow每个角色。
this answer中的信息有助于指导我创建这些课程。
如果相关:
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
[edit]我似乎偶然发现了一个解决方案:在同步()中删除对str("");
的调用,使其在所有测试平台上打印预期输出。然而,我的问题仍然存在,因为我不明白为什么这个电话打破了stringbuf。[/ edit]