前言:涉及代码版权所属:sylar的博客 – C++,vimer,linux,推荐系统,搜索系统,分布式框架
我自己先摘抄优秀干净的代码以作备忘使用和学习
宏替换
- 亮点在于这就是自己想做,但一直不知道怎么做的,减少编辑的代码,使代码简洁的技巧(
LogLevel
的声明部分没写出来,但函数的核心逻辑已经能看出来了) - 用
#
将宏取成字符串string
或char*
- 宏有换行
\
反斜杠表示之 - 宏是简单逻辑语句
const char* LogLevel::ToString(LogLevel::Level level) { switch(level) { #define XX(name) \ case LogLevel::name: \ return #name; \ break; XX(DEBUG); XX(INFO); XX(WARN); XX(ERROR); XX(FATAL); #undef XX default: return "UNKNOW"; } return "UNKNOW"; } LogLevel::Level LogLevel::FromString(const std::string& str) { #define XX(level, v) \ if(str == #v) { \ return LogLevel::level; \ } XX(DEBUG, debug); XX(INFO, info); XX(WARN, warn); XX(ERROR, error); XX(FATAL, fatal); XX(DEBUG, DEBUG); XX(INFO, INFO); XX(WARN, WARN); XX(ERROR, ERROR); XX(FATAL, FATAL); return LogLevel::UNKNOW; #undef XX }
可变参数与va_list 与 va_start() 与 va_end()
- 这是什么? 我没见过,细看了下大概明了逻辑,但还是有疑点,注释上
LogEvent::format(const char* fmt, va_list al)
没理解到这个函数- 也没理解到
va_end()
void LogEvent::format(const char* fmt, ...) { // al表示 fmt之后的(用...表示的)所有可变参,将 a1理解成容器 va_list al; // 从 a1这一系列可变参中取出第一个参数放到 fmt, a1就是取之后剩下的 // ? 如果 a1只容纳了一个元素呢? va_start(al, fmt); format(fmt, al); va_end(al); } void LogEvent::format(const char* fmt, va_list al) { char* buf = nullptr; int len = vasprintf(&buf, fmt, al); if(len != -1) { m_ss << std::string(buf, len); free(buf); } }
- 看这种解释可能更接近于正确的答案
void LogEvent::format(const char* fmt, ...) { // a1理解成容器,表示包括可变参在内的所有参数,它的作用就是把参数打包成一个容器 va_list al; // a1中自 fmt开始的元素放在 a1中,就是在 a1中剥离 fmt va_start(al, fmt); // 调用下面的LogEvent::format(const char* fmt, va_list al)函数 format(fmt, al); va_end(al); } void LogEvent::format(const char* fmt, va_list al) { char* buf = nullptr; int len = vasprintf(&buf, fmt, al); if(len != -1) { m_ss << std::string(buf, len); free(buf); } }