我正在尝试实现在不需要时不产生开销的日志记录(即根本不应该执行任何方法调用).我想要没有开销,因为它是低延迟代码.我刚刚添加#define ENABLE_LOGS到我的标题类中,现在它看起来像那样(你可以忽略细节)
#pragma once
#include <string>
#include <fstream>
#define ENABLE_LOGS
namespace fastNative {
class Logger
{
public:
Logger(std::string name_, std::string fileName, bool append = false);
~Logger(void);
void Error(std::string message, ...);
void Debug(std::string message, ...);
void DebugConsole(std::string message, ...);
void Flush();
static Logger errorsLogger;
static Logger infoLogger;
private:
FILE* logFile;
bool debugEnabled;
};
}
Run Code Online (Sandbox Code Playgroud)
每当我需要使用某种方法时,我应该像这样围绕它:
#ifdef ENABLE_LOGS
logger.Debug("seq=%6d len=%4d", seq, length_);
#endif
Run Code Online (Sandbox Code Playgroud)
这是错误的错误(我可以忘记环绕)并使代码变脏.我能以某种方式修改我的代码而不是#ifdef每次都使用吗?
在C#中我喜欢Conditional我想我需要类似c ++的东西.
Too*_*one 13
首先,看看已经存在的东西是有意义的.这是一个常见问题,很多人以前都会解决它.例如,请参阅stackoverflow问题C++日志框架建议,以及Dobbs博士在C++中的高度可配置日志框架.
如果你自己动手,那么你应该从这里得到一些好主意.我过去使用过几种方法.一种是使条件本身有条件地定义
#ifdef ENABLE_LOGS
#define LOG(a,b,c) logger.Debug(a, b, c)
#else
#define LOG(a,b,c)
#endif
Run Code Online (Sandbox Code Playgroud)
另一种方法是有条件地定义日志记录类本身.非日志版本的所有内容都是空语句,您依赖于编译器优化所有内容.
#ifdef ENABLE_LOGS
class Logger
{
public:
Logger(std::string name_, std::string fileName, bool append = false);
~Logger(void);
void Error(std::string message, ...);
void Debug(std::string message, ...);
void DebugConsole(std::string message, ...);
void Flush();
static Logger errorsLogger;
static Logger infoLogger;
private:
FILE* logFile;
bool debugEnabled;
};
#else
class Logger
{
public:
Logger(std::string name_, std::string fileName, bool append = false) {}
~Logger(void) {}
void Error(std::string message, ...) {}
void Debug(std::string message, ...) {}
void DebugConsole(std::string message, ...) {}
void Flush() {}
};
#endif
Run Code Online (Sandbox Code Playgroud)
您可以将您的Logger实现放在ENABLE_LOGS宏控制下的cpp文件中.这种方法的一个问题是您希望确保定义接口,以便编译器可以优化所有内容.因此,例如,使用C字符串参数type(const char*).在任何情况下const std::string&都是优选的std::string(后者确保每次有呼叫时都有一个字符串副本).
最后,如果您采用第一种方法,则应该将所有内容封装起来,do() { ... } while(0)以确保在使用宏时可能不会出现奇怪的行为.
使用宏有一种方法(llvm的方式).
#ifdef ENABLE_LOGS
#define DEBUG(ARG) do { ARG; } while(0)
#else
#define DEBUG(ARG)
#endif
Run Code Online (Sandbox Code Playgroud)
然后用它作为:
DEBUG(logger.Debug("seq=%6d len=%4d", seq, length_););
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
519 次 |
| 最近记录: |