C ++单独的成员流重载<<

时间:2013-08-27 10:50:27

标签: c++ logging ostream

我希望为不同严重程度的日志编写一个包含多个流的记录器:

class Logger{
public:
    std::ostream& errStream;
    std::ostream& warnStream;
}

这样我就可以使用这些流:

Logger L;
L.errStream << "This is an error message.";
L.warnStream << "This is a warning message.";

问题是,如何重载运算符&lt;&lt;对于每个流分别?含义我想根据写入哪个流采取不同的操作。

如果有帮助,我已经有了errWrite和warnWrite的成员函数,它们以std :: string作为参数:

void errWrite(std::string);
void warnWrite(std::string);

要使用这些,我会这样做:

Logger L;
L.errWrite("This is an error message.");
L.warnWrite("This is a warning message.");

这些的问题在于它们不会替换std :: cout和std :: cerr,我的代码已经填充了。我试图开发一些可以轻松放入现有代码的东西。所以最终我想要:

  1. 为不同成员分别重载运算符的方法。
  2. 我正在尝试做的另一种方法。
  3. 感谢。

3 个答案:

答案 0 :(得分:2)

要重载operator<<,类型需要不同。

因此,为此,您必须创建一个新类来替换std::ostream,例如owarnstreamoerrstream

我认为这样的事情会起作用:

class oerrstream
{
 private:
   std::ostream& st;

 public:
   oerrstream(std::ostream &stream) : st(stream) {}
   std::ostream& getStream() { return st; };
};

然后你可以使用:

覆盖它
oerrstream& operator<<(oerrstream &es, const std::string& s)
{
   es.getStream() << s;
   return es;
}

请记住,您需要覆盖所有输出操作系统......使用模板可以做到这一点,如下所示:

template <typename T>
oerrstream& operator<<(oerrstream &es, T t)
{
   es.getStream() << t;
   return es;
}

答案 1 :(得分:1)

您可以采用IO操纵器方法:

#include <iostream>
#include <string>

class Logger {
public:
    Logger()
        : errStream(std::cerr)
        , warnStream(std::cout)
        , active(&errStream)
    { }

    Logger& operator<<(const std::string& str)
    {
        *active << str;
        return *this;
    }

    Logger& operator<<(Logger&(*manip)(Logger&))
    {
        return manip(*this);
    }

private:
    std::ostream& errStream;
    std::ostream& warnStream;
    std::ostream* active;

    friend Logger& err(Logger&);
    friend Logger& warn(Logger&);
};

Logger& err(Logger& obj)
{
    obj.active = &obj.errStream;
    return obj;
}

Logger& warn(Logger& obj)
{
    obj.active = &obj.warnStream;
    return obj;
}

int main()
{
    Logger l;
    l << err << "error\n";
    l << warn << "warning\n";
}

答案 2 :(得分:0)

  

含义我想根据写入哪个流来执行不同的操作。

不确定“不同行为”是什么意思,但这是一种解释:

class Logger{
private:
    std::ostream& errStream;
    std::ostream& warnStream;

public:

    enum { err, warn } stream_type;


    std::ostream& get(stream_type const st)
    {
        // different actions per stream:
        switch(st)
        {
        case err:
            return errStream << "Error [" << gettime_function() << "] ";
        case warn:
            return warnStream << "Warning: ";
        }
    }
};

编辑:

如果您想要自己专门化流,您可以轻松定义模板化输出运算符:

class ErrorStream
{
     std::ostream& underlying_;
public:
    ErrorStream(std::ostream& underlying) : underlying_(underlying) {}
    template<typename T> friend ErrorStream& operator << (
        ErrorStream& out, const T& arg)
    {
        // custom action for error stream goes here
        out.underlying_ << arg;
        return out;
    }
};

此运算符适用于operator<< (std::ostream&, const T&)适用的任何T。