0

所以我有一个 C++ 程序,它通常在执行时会将内容写入日志文件。这是使用 fstream 完成的。但是,现在我想包含关闭日志记录的功能。本质上,我的代码如下所示:

bool isLogging;
fstream* logFilePtr;

在我的代码中,有一堆语句,如:

(*logFilePtr) << "    Kernel call time in seconds: " << kTime << endl;
...

现在,如果“isLogging”为真,我不想打印这些。我可以用一堆 if 语句围绕它们,但我更喜欢比这更干净的东西。我认为有某种方法可以获取 C++ 流并将其重定向到“无”,这样当使用 << 运算符时,什么都不会打印。

有谁知道如何重定向流,或者对如何以优雅的方式处理这个有任何其他想法?

谢谢,科林

4

7 回答 7

6

你可以把它包在一个班级里。

class Log {
  Log (fstream &s) : stream(s), enabled(false) { }
  void Enable () { enabled = true; }
  void Disable () { enabled = false; }

  template<class T>
  Log &operator<< (T const& rhs) {
    if (enabled) stream << rhs;
    return *this;
  }

private:
  fstream &stream;
  bool enabled;
};

这未经测试..但基本思想应该在那里。

于 2009-07-09T14:51:51.360 回答
4

看看rdbuf成员函数。您可以创建一个丢弃流缓冲区并将其与您的流相关联。

struct nullbuf: std::streambuf
{
    int overflow(int c) { return traits_type::not_eof(c); }
};
于 2009-07-09T14:56:13.690 回答
1

std::iostream 不允许操作系统级别的重定向,但是,您可以在 std::iostreams 之间共享 std::streambufs:

int main() {
    // redirect stdout to stderr:
    std::streambuf * const oldstdout = std::cout.rdbuf();
    std::cout.rdbuf( std::cerr.rdbuf() );

    // test
    std::cout << "Hello ";
    std::cerr << "World" << std::endl;

    // re-set, so streambufs are properly deleted:
    std::cout.rdbuf( oldstdout );

    // test
    std::cout << "Hello ";
    std::cerr << "World" << std::endl;

    return 0;
}

这样,您可以将日志重定向到其他地方(例如“/dev/null”:),或者,如果您遵循 avakar 的回答,请使用 nullbuf。

于 2009-07-09T15:04:38.773 回答
0
std::ostream& Debug(int level) {
  std::clog.clear(levell <= shown_level ? std::ios_base::goodbit: std::ios_base::badbit);
  return std::clog;
}

来自comp.lang.c++

于 2009-07-09T15:07:17.630 回答
0

在“关于如何处理这个问题的其他想法”下:

  1. 使用状态模式消除对所有代码进行 if 检查的需要。
  2. 将策略模式(编译时策略模式)与 Logging 策略对象一起使用。
于 2009-07-09T15:17:44.223 回答
0

平台?如果您在 unix 下,您可以将文件写入 /dev/null

于 2009-07-09T14:53:04.540 回答
0

我使用 POCO 库的日志记录功能。它支持配置通道 - 控制台,文件,两者。配置输出格式和日志级别(跟踪、调试、错误等)。然后,我将日志记录功能与诸如

inline void logError(const std::string & str)
{
#ifdef COMPILE_ERROR_LOGGING
   g_pMyPocoLogger->error(str);
#endif
}

您可以选择不使用该库,但我仍然建议使用包装器围绕您的日志记录。

于 2009-07-09T14:54:17.330 回答