本文主要是介绍如何为 glog 的宏重载 <<,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
<2023-03-21 周二>
如何为glog的宏重载<<
为什么要为glog重载<<呢?因为如果在windows平台上只想在Debug模式下使用glog,不重载<<的话,可能大概率会写出下面这样的代码,并且如果有一处漏掉#ifdef语句的话,Release模式下编译也会失败;此外导致代码非常不简洁:
#ifdef _DEBUGLOG(ERROR) << "error";
#endif
所以我想在编译Release版本时在没有这种预处理指令#ifdef时glog的宏依然能编译通过且没有任何作用,所以必须重载<<。最终我找到了解决办法,参考了glog的源代码LogMessage类的写法。
// xxx.h#ifdef _DEBUG
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <glog/logging.h>#pargma comment(lib, "glogd.lib")
#else // _DEBUG
class log2void : public std::ostream {
public:log2void() : std::ostream(NULL) {OutputDebugStringA("log2void ctor");}
};extern log2void L2V;#define LOG_IF(a, b) L2V
#define LOG(a) L2V
#define VLOG(a) L2V
#endif // _DEBUG
// xxx.cpp#include "xxx.h"#ifdef _DEBUG
#else
log2void L2V;
#endif
说明:
- 为什么要有全局变量
L2V?因为不用全局变量的话,在每次调用glog宏时都会有log2void的构造成本产生,经过调试发现构造涉及的初始化类较多,个人认为影响性能。或者也可以直接在头文件中定义static log2void L2V;静态变量,也减少了构造的次数,只不过每个源文件中都会有一个L2V的实例,比全局变量的效果次点。 - 为什么要继承自
std::ostream?这主要就是为了方便,可以利用std::ostream的代码,不用自己重载<<,要知道在std::ostream中已经重载好的<<函数有不下十几个,因为要考虑参数类型的问题、返回值问题、一个语句中有多个<<等问题。之前就自己写<<重载函数,返回void,这种写法对于一个语句中有多个连续的<<情况,编译时就会报错了。 - 为什么
std::ostream(NULL)初始化为NULL?因为这样的话,流的good()函数就返回false,可以自己调试<<的代码来理解。这样就减少了<<在Release版本中运行的指令的数量,避免日志输出对程序运行造成性能影响。
这篇关于如何为 glog 的宏重载 <<的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!