我们有一个基于带有自定义流缓冲区的std :: ostream的日志实现。我们通过Schwarz计数器实现我们的应用程序的日志类实例。
为了避免将我们的低级类与我们的日志实现耦合,我们可以将引用传递给std :: ostream。通过这种方式,我们的低级类可以记录到std :: cout,std :: cerr或通过Schwarz计数器创建的实例。
我有一个问题。日志实现通过流操作符的重载来设置其严重性:
// Overload the << operator to set the log message severity
inline CLogStream& operator << (CLogStream& myLogStream, eMsgType::type msgTypeCurrent)
{
myLogStream.SetMsgTypeCurrent(msgTypeCurrent);
return ( myLogStream ) ;
}
这允许我们像这样使用记录器:
CLog::Main << CLog::MSG_FATAL << "Fatal error" << std::endl;
我想创建一个对应用程序的日志实例的引用,该实例被锁定到特定的严重性。这样,我可以传递我们的实用程序类两个std :: ostream引用。其中一个用于正常报告,另一个用于错误报告。这些可以设置为std :: cout和std :: cerr,或者设置为引用我们的日志对象实例的某种对象。
不幸的是std :: ostream运算符&lt;&lt;据我所知,我不是虚拟的,所以我不确定如何设计这样的对象。
有什么想法吗?
答案 0 :(得分:1)
iostream
具有虚拟成员函数(具体为~ios_base
),因此您可以在dynamic_cast
中执行operator<<
:
inline std::ostream &operator<<(std::ostream &os, eMsgType::type msgTypeCurrent) {
if (CLogStream *myLogStream = dynamic_cast<CLogStream *>(&os)) {
myLogStream->SetMsgTypeCurrent(msgTypeCurrent);
} else {
os << "TYPE: " << static_cast<typename std::underlying_type<eMsgType::type>
::type>(msgTypeCurrent) << ": ";
}
return os;
}
答案 1 :(得分:1)
如果严重性的设置是持久的,那么这两个行都会导致严重致命的日志条目
CLog::Main << CLog::MSG_FATAL << "Log entry 1: " << some_data << std::endl;
CLog::Main << "Log entry 2: " << some_other_data << std::endl;
然后您的日志记录类已经正确设计,可以作为通用ostream&
传递。您只需要为实用程序类支持的不同日志级别使用单独的记录器实例。
这是在假设记录器类已从ostream
继承以利用现有operator<<
重载的情况下编写的。
在这种情况下,operator<<
和some_data
的{{1}}已完全不知道输出会转到日志流。
答案 2 :(得分:1)
了解ios_base::iword()
。它允许您访问流对象中的long
值数组,您可以使用这些值来存储标志和特殊值等内容。