我希望为不同严重程度的日志编写一个包含多个流的记录器:
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,我的代码已经填充了。我试图开发一些可以轻松放入现有代码的东西。所以最终我想要:
感谢。
答案 0 :(得分:2)
要重载operator<<
,类型需要不同。
因此,为此,您必须创建一个新类来替换std::ostream
,例如owarnstream
和oerrstream
。
我认为这样的事情会起作用:
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。