1

在我的 C# 项目中,我喜欢使用ConditionalAttribute并发现它非常有用。我有很多用于日志记录的类,只需使用设置或取消设置的相应条件属性重新编译即可打开或关闭日志记录(没有开销)。

// this code likely is not good as HedgerControllerLogger better to be singleton
// please ignore that

public class HedgerControllerLogger
{
    private StreamWriter swLog;

    public HedgerControllerLogger()
    {
        swLog = new StreamWriter("logsGeneral/logHedgerController.txt") { AutoFlush = true };
    }

    [Conditional("LOG_HEDGER_CONTROLLER")]
    public void Log(string message)
    {
        swLog.WriteLine(DateTimePrecise.Instance.CurDateTime().ToString("H:mm:ss:ffffff") + ' ' + message);
    }

}

我怎样才能对 c++ 产生相同的效果?我应该使用类似的东西吗?可能一些现有的日志库具有相同的功能,可能boost吗?谢谢!

4

2 回答 2

1

您可以使用预处理器:

#ifdef ENABLE_LOGGING
  void log(const std::string& message) { /* do logging*/}
#else
  void log(const std::string&){}
#endif

你也可以用模板做类似的事情,但为什么要过于复杂呢?

于 2013-04-24T16:00:19.847 回答
0

我建议看看如何TRACE/ATLTRACE提供类似的宏(如果我是正确的,你正在使用 Visual Studio)。一般来说,它们归结为在 DEBUG 构建中进行跟踪调用,在 RELEASE 构建中进行无操作。这是一个例子:

struct CTrace
{
    static void CTrace::Trace(LPCTSTR lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        TCHAR szBuffer[1024];
        int nSize = sizeof(szBuffer)/sizeof(szBuffer[0]);
        int nBuf = _vsntprintf(szBuffer, nSize, lpszFormat, args);          
        OutputDebugString(szBuffer); // write to debug output
        va_end(args);
    }    
};

#ifdef _DEBUG   
#define TRACE               CTrace::Trace
#else  
#define TRACE               true ? (void)0 : CTrace::Trace
#endif // _DEBUG

然后在代码中你有类似的东西:

TRACE("value is %d", 34);

在 DEBUG 构建中,它被编译为:

CTrace::Trace("value is %d", 34);

在发布版本中,它变成:

true ? (void)0 : CTrace::Trace("value is %d", 34);

然后由编译器优化掉。您可以通过检查生成的代码来验证它。

于 2013-04-24T16:41:03.013 回答