本文主要是介绍如何为 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 的宏重载 <<的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!