如何为 glog 的宏重载 <<

发布时间:2024年01月16日

<2023-03-21 周二>

如何为glog的宏重载<<

为什么要为glog重载<<呢?因为如果在windows平台上只想在Debug模式下使用glog,不重载<<的话,可能大概率会写出下面这样的代码,并且如果有一处漏掉#ifdef语句的话,Release模式下编译也会失败;此外导致代码非常不简洁:

#ifdef _DEBUG
    LOG(ERROR) << "error";
#endif

所以我想在编译Release版本时在没有这种预处理指令#ifdefglog的宏依然能编译通过且没有任何作用,所以必须重载<<。最终我找到了解决办法,参考了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

说明:

  1. 为什么要有全局变量L2V?因为不用全局变量的话,在每次调用glog宏时都会有log2void的构造成本产生,经过调试发现构造涉及的初始化类较多,个人认为影响性能。或者也可以直接在头文件中定义static log2void L2V;静态变量,也减少了构造的次数,只不过每个源文件中都会有一个L2V的实例,比全局变量的效果次点。
  2. 为什么要继承自std::ostream?这主要就是为了方便,可以利用std::ostream的代码,不用自己重载<<,要知道在std::ostream中已经重载好的<<函数有不下十几个,因为要考虑参数类型的问题、返回值问题、一个语句中有多个<<等问题。之前就自己写<<重载函数,返回void,这种写法对于一个语句中有多个连续的<<情况,编译时就会报错了
  3. 为什么std::ostream(NULL)初始化为NULL?因为这样的话,流的good()函数就返回false,可以自己调试<<的代码来理解。这样就减少了<<Release版本中运行的指令的数量,避免日志输出对程序运行造成性能影响。
文章来源:https://blog.csdn.net/ftuc5dn/article/details/135615309
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。