如何使用cout样式接口编写记录器类(logger<<“错误:”<<< val<< endl;)

时间:2010-02-10 09:09:02

标签: c++ operators operator-overloading logging cout

我想创建一个记录器类,使用这样的功能:

Logger log;
log << "Error: " << value << "seen" << endl;

这应该打印一个自定义格式的消息。例如。 “12-09-2009 11:22:33看到错误5”

我的简单课程目前看起来像这样:

class Logger {
    private:
        ostringstream oss;
    public:
        template <typename T>
        Logger& operator<<(T a);
}

template <typename T>
Logger& Logger::operator<<(T a) {
    oss << a;
    return *this;
}

void functionTest(void) {
    Logger log;
    log << "Error: " << 5 << " seen";
}

这将导致oss正确地拥有缓冲区“Error:5 seen”。但我不知道我需要编写/修改其他功能,以便在屏幕上打印某些内容。 有没有人知道如何使这个工作或是否有另一种方法来设计这个类以使我的功能工作?

5 个答案:

答案 0 :(得分:4)

每个std::ostream后面都是streambuf。可以通过std::stream::rdbuf()检索和设置它。特别是,它可以被包装 - 您可以提供一个后处理流文本的streambuf对象。 (后期处理表示您无法区分std::cout << 123;std::cout << "123";

在您的特定情况下,后处理非常简单。在每行的开头,您要插入一些字节。这仅仅意味着你应该跟踪你是否已经输出了当前行的前缀。如果没有,请执行此操作并设置标志。每当您看到换行符时,请重置它。您的streambuf包装器只有一个bool状态。

答案 1 :(得分:1)

据我所知,你的记录器与ostringstream没什么区别。它只需要给出的内容并将其输出到字符串流。如果你想像这样使用它,可以为Logger编写一个析构函数,将字符串输出到cout。

Logger::~Logger()
{
    std::cout<<getcurrentDateTimeAsString()<<" "<<oss.str()<<std::endl;
}

但是,当然,如果在整个程序中创建并使用Logger *,这将毫无意义。

答案 2 :(得分:1)

查看Compile time optimization - removing debug prints from release binaries中提出的简单记录器。应该足以满足您的需求。 BR, Gracjan

答案 3 :(得分:1)

问题是选择何时以及如何通过线路同步信息?因此无论是否缓冲,除了控制EOL和线路上的信息 - 冲洗它或直接输出外别无选择。

即使将析构函数用作EOL / Flush,

{ log << [anything]; }作为内联本地堆栈括号语法,用于调用退出括号的log的析构函数,或者必须使用std :: endl。

除非使用某些追加运算符(例如'&lt;&lt;')实现元对象或者“+”,你一直在结束,有义务使用一种明确的方式来结束这一行,或者冲洗。

答案 4 :(得分:0)

这(来自this post)做你想要的,但它强迫你用std :: endl结束每一行:

class Logger {
    private:
        ostringstream oss;
    public:
        template <typename T>
        Logger& operator<<(T a);

    Logger& operator<<( std::ostream&(*f)(std::ostream&) )
    {
        if( f == std::endl )
        {
            std::cout << "12-09-2009 11:22:33" << oss.str() << std::endl;   
            oss.str("");
        }
        return *this;
    }
};

template <typename T>
Logger& Logger::operator<<(T a) {
    oss << a;
    return *this;
}

void functionTest(void) {
    Logger log;
    log << "Error: " << 5 << " seen" << std::endl;
}

int main()
{
    functionTest();
}

编辑:根据您的评论,它似乎不是您想要的。然后我建议你按照MSalters的说法做。