学习sylar

562 阅读2分钟

前言:涉及代码版权所属:sylar的博客 – C++,vimer,linux,推荐系统,搜索系统,分布式框架

我自己先摘抄优秀干净的代码以作备忘使用和学习

宏替换

  • 亮点在于这就是自己想做,但一直不知道怎么做的,减少编辑的代码,使代码简洁的技巧(LogLevel的声明部分没写出来,但函数的核心逻辑已经能看出来了)
  • #将宏取成字符串stringchar*
  • 宏有换行\反斜杠表示之
  • 宏是简单逻辑语句
    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);
        }
    }