派生自std :: stringbuf - overflow()未被可靠地调用

时间:2018-01-18 16:27:24

标签: c++ ostream

我正在尝试创建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]

0 个答案:

没有答案