在C++项目中,一些场景下,可能会用到一个空的日志类,覆盖项目中的日志实现,让项目不打印日志,比如:
- 屏蔽某个类库中的日志(因为库的日志打印机制设计的不够好)
- 单例测试中代码中,屏蔽项目日志
应对以上需求,本文实现了一个不打印日志的类,有如下特点:
- 覆盖项目中日志的宏定义,比如LOG_INFO等,不打印日志
- 重载operator<<操作符的实现
实现中有哪一些陷阱呢?主要在std::endl上面。
在重载operator<<操作符的时候,使用LOG_INFO<<"log"<<std::endl;
时,会提示,std::endl是未知类型(unresolved overloaded function type)
关于std::endl的本质,是一个函数模板,本文不做详细阐述,只给出实现方法。
代码如下,使用c++11标准实现:
#ifdef DISABLE_PRJ_LOG
#undef LOG_DEBUG
#undef LOG_INFO
#undef LOG_WARN
#undef LOG_ERROR
#undef LOG_FATAL
#include
#include
class BlankLogObject {
public:
static BlankLogObject& Ins() {
static BlankLogObject obj;
return obj;
}
BlankLogObject& operator<<(void* in) { return *this; }
BlankLogObject& operator<<(char in) { return *this; }
BlankLogObject& operator<<(const char* in) { return *this; }
BlankLogObject& operator<<(const std::string& in) { return *this; }
BlankLogObject& operator<<(int16_t in) { return *this; }
BlankLogObject& operator<<(int32_t in) { return *this; }
BlankLogObject& operator<<(uint32_t in) { return *this; }
BlankLogObject& operator<<(int64_t in) { return *this; }
BlankLogObject& operator<<(uint64_t in) { return *this; }
BlankLogObject& operator<<(float in) { return *this; }
BlankLogObject& operator<<(double in) { return *this; }
BlankLogObject& operator<<(BlankLogObject& in) { return *this; }
BlankLogObject& operator<<(std::ostream& in) { return *this; }
BlankLogObject& operator<<(std::ostream (*in)(std::ostream&)) { return *this; }
typedef std::basic_ostream > endl_type;
BlankLogObject& operator<<(endl_type& (*in)(endl_type&)) { return *this; }
};
}
#define LOG_DEBUG rec::BlankLogObject::Ins()
#define LOG_INFO rec::BlankLogObject::Ins()
#define LOG_WARN rec::BlankLogObject::Ins()
#define LOG_ERROR rec::BlankLogObject::Ins()
#define LOG_FATAL rec::BlankLogObject::Ins()
#endif
int main() {
LOG_INFO << "skf" << 123 << 0.1 << std::endl;
return 0;
}