使用类似cout的表示法在C ++中管理日志流

时间:2010-12-30 13:49:37

标签: c++ logging printing operator-overloading

我有一个用c ++编写的类,以便为我的应用程序编写日志文件。我已经构建了类并且它可以工作,它是这样的:

class Logger {
   std::string _filename;
public: 
   void print(std::string tobeprinted);
}

嗯,直观地说,为了在日志文件中打印一行,对于Logger的对象,只需要执行以下操作:

Logger mylogger("myfile.log");
mylogger.print(std::string("This is a log line"));

好。使用方法方法与使用更好的模式(例如<<是。 我想做以下事情:

Logger mylogger("myfile.log");
mylogger << "This is a log line";

这就是全部。我想我必须重载&lt;&lt; operator ...但是使用这个签名(经典的签名)重载:

ostream& operator<<(ostream& output, const MyObj& o);

但我没有ostream ...... 那么,我应该这样做吗?

Logger& operator<<(Logger& output, const std::string& o);

这是正确的方法吗? 感谢

4 个答案:

答案 0 :(得分:6)

class Log
{
public:

    enum Level { Debug, Error, Info };

    static ostream& GetStream() { return cout; }
    static bool IsLevelActive(Level l) { return true; }
};

#ifndef NO_LOG
#define LOG_ERROR(M)   do { if (Log::IsLevelActive(Log::Error))   (Log::GetStream() << "ERR: " << M << "\n"); } while (false)
#define LOG_INFO(M)    do { if (Log::IsLevelActive(Log::Info))    (Log::GetStream() << "INF: " << M << "\n"); } while (false)
#define LOG_WARNING(M) do { if (Log::IsLevelActive(Log::Warning)) (Log::GetStream() << "WRN: " << M << "\n"); } while (false)
#else
#define LOG_ERROR(M)
#define LOG_INFO(M)
#define LOG_WARNING(M)
#endif

struct MyObject {
    int a, b;
};

ostream& operator<<(ostream& ostr, const MyObject& obj) {
    ostr << "(a=" << obj.a << ", b=" << obj.b << ")";
    return ostr;
}

void test() {
    int v1 = 42;
    int v2 = 43;
    LOG_INFO("value1=" << v1 << ", value2=" << v2);

    MyObject o = {1, 2};
    LOG_INFO("obj=" << o);
}

答案 1 :(得分:4)

为什么不简单地使Logger成为std :: ostream或std :: ostringstream的子类?然后,所有这些功能都将实现。

答案 2 :(得分:1)

是的,这是正确的方法。但你必须添加&lt;&lt;对于需要记录的每种数据类型,运算符都会重载。

答案 3 :(得分:0)

您真的不想创建全新的流,因为您需要重新定义所有流运算符。如果要完全更改数据转换为字符数据的方式,则只能这样做。 (伊克)。

我最好找到的是创建一个类,它将跟踪流并在销毁时将其内容发送到我选择的目标(记录器)。结合一些宏,可以为您提供所需的内容:用于记录的流语法。

Boost实际上有一些类可以帮助解决这个问题。请看iostreams