Question List in May, 2023
1、工作记录
工作内容不对外公开。
2、日常积累
#cplusplus
2.1 C++ 实现 LOG 输出
可以在析构函数中输出换行符以便使用 LOG(INFO) << "hello"
时直接在末尾添加换行符,另外需要注意的就是宏展开中 ##
是用于宏代码的拼接,可以将括号内的参数直接拼接到内容中。
class LogMessage{
public:
LogMessage(std::string message):_message(message){}
~LogMessage(){
std::cout << std::endl;
}
std::ostream& stream(){
std::ostream& os = std::cout;
os << "[" << _message << "]: ";
return os;
}
private:
std::string _message;
};
#define COMPACT_LOG_INFO LogMessage("INFO")
#define COMPACT_LOG_WARNING LogMessage("WARNING")
#define COMPACT_LOG_ERROR LogMessage("ERROR")
#define LOG(severity) COMPACT_LOG_ ## severity.stream()
2.2 C++ 反射机制
如果要实现反射,一般来实现有两种:一种是静态反射,利用宏和模板在编译器就将反射函数对应展开,因此没有什么开销;另一类是动态反射,程序中对每一个注册过反射类型的对象保存着一张表,通过查找表去做相应动作。总体来说,任何语言实现反射都离不开保存一张查找表,然后对应展开的过程,无非就是静态动态,编译器做还是用户做了。
#include <unordered_map>
#include <string>
#include <iostream>
#include <stdlib.h>
class Test
{
public:
void a(){std::cout<<"I am a"<<std::endl;}
void b(){std::cout<<"I am b"<<std::endl;}
void c(){std::cout<<"I am c"<<std::endl;}
std::unordered_map<std::string,void (Test::*)()>funcList;
Test(){
funcList.emplace("a",&Test::a);
funcList.emplace("b",&Test::b);
funcList.emplace("c",&Test::c);
};
public:
void demo(){
(this->*funcList.at("c"))();
}
};
int main(void){
Test test;
void (Test::*ptr)()=test.funcList.at("a");
(test.*ptr)(); // 第一种调用方法
(test.*test.funcList.at("b"))(); // 第二种调用方法
test.demo(); // 第三种调用方法
return 0;
}
//结果:
//I am a
//I am b
//I am c
参考文献
知乎. # 借助宏和模板技术实现C++的简单静态反射[EB/OL].
知乎. # C++模板寄算:简单的成员反射[EB/OL].
知乎. # 如何优雅的实现C++编译期静态反射[EB/OL].
CSDN 博客. # C++ 对象的成员函数反射[EB/OL].
CSDN 博客. # C++语言学习(十四)——C++类成员函数调用分析[EB/OL].
CSDN 博客. # C++类成员函数模拟实现反射[EB/OL].