从没有虚函数的C ++类继承

时间:2013-02-12 10:33:32

标签: c++ dependencies

我们有一个基于带有自定义流缓冲区的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;据我所知,我不是虚拟的,所以我不确定如何设计这样的对象。

有什么想法吗?

3 个答案:

答案 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值数组,您可以使用这些值来存储标志和特殊值等内容。