## 反射器实现
C++语言没有java和go的反射机制,想要实现需要用将定义类注册到map中存储起来,待到需要用时,直接根绝类名从map中获取实例。C++最常见的是用宏定义实现,但很多基本用宏实现的版本理解起来非常困难,所以我用较少宏实现C++的反射功能,代码如下:
```
/**
* @brief C++反射器
*/
#ifndef _REFLECTOR_H_
#define _REFLECTOR_H_
#include <iostream>
#include <unordered_map>
#include <memory>
#include <functional>
namespace even {
class Reflector {
public:
typedef std::function<void*()> Func;
void* CreateObject(const std::string& name)
{
if (mapFunction_.count(name))
return mapFunction_[name]();
return nullptr;
}
void Regist(const std::string& name, Func&& func)
{
mapFunction_[name] = func;
}
static Reflector& Instance()
{
static Reflector instance;
return instance;
}
private:
Reflector() {}
std::unordered_map<std::string, Func> mapFunction_;
};
class Register {
public:
typedef std::function<void*()> Func;
Register(const std::string& name, Func&& func)
{
Reflector::Instance().Regist(name, std::forward<Func>(func));
}
};
/**
* 抽象基类不能注册
*/
#define REGISTER(class_name) \
Register g_register_##class_name(#class_name, []() { \
return new class_name(); \
});
}
#endif
```
## 反射器运用
常用的反射功能一般为根据类名直接创建实例,返回基类的指针,这样可以不用写很多 if 和 else 根据类名创建不同实例的判断,而且后期加入其它派生类也不用修改代码,非常方便且易于维护,特别是服务器实现 RPC 的功能反射机制非常有用。
运用如下:
```
#include "reflector.h"
using namespace even;
class Base {
public:
explicit Base() = default;
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
REGISTER(Base); // 注册
class DeriveA : public Base {
public:
void Print() override
{
std::cout << "DeriveA" << std::endl;
}
};
REGISTER(DeriveA); // 注册
class DeriveB : public Base {
public:
void Print() override
{
std::cout << "DeriveB" << std::endl;
}
};
REGISTER(DeriveB); // 注册
/**
* 实例创建宏,返回基类指针,相当于new的作用,需要自己回收
*/
#define BASE_CREATE(name) reinterpret_cast<Base*>(Reflector::Instance().CreateObject(name))
int main()
{
std::shared_ptr<Base> p1(BASE_CREATE("Base"));
p1->Print();
std::shared_ptr<Base> p2(BASE_CREATE("DeriveA"));
p2->Print();
std::shared_ptr<Base> p3(BASE_CREATE("DeriveB"));
p3->Print();
return 0;
}
```
运行结果如下:
```
Base
DeriveA
DeriveB
```
- 空白目录
- 算法
- 排序
- 冒泡排序
- 选择排序
- 插入排序
- 归并排序
- 快速排序
- 计数排序
- 桶排序
- 基数排序
- 希尔排序
- 堆排序
- 二分查找
- 最小堆
- 最小索引堆
- 平衡二叉树(AVL tree)
- bitmap位图
- 布隆过滤器
- hashmap
- topK
- 跳表
- LRU Cache
- kmp
- 最小堆和堆排序
- 最短路径
- C++
- 运行时类型判断RTTI
- C++反射
- 手动实现智能指针
- 序列化实现
- rpc实现
- std::forward
- 函数指针的妙用
- C/C++
- std::function
- 同步队列
- 线程池实现
- std::promise
- 深入理解虚函数
- extern "C" 关键字讲解
- 大端小端的区别
- 简历
- 简历1
- redis
- 数据结构和对象
- sds
- list
- zskiplist
- 腾讯云redis面试题总结
- redis集群部署
- LeetCode
- 目标
- go基础
- 算法快速入门
- 数据结构篇
- 二叉树
- 链表
- 栈和队列
- 二进制
- 基础算法篇
- 二分搜索
- 排序算法
- 动态规划
- 算法思维
- 递归思维
- 滑动窗口思想
- 二叉搜索树
- 回溯法
- 其他
- 剑指offer
- 笔记
- git代理加速
- Linux
- vim大法
- vscode远程不能跳转
- cmake
- 设计模式
- 单例模式
- 简单工厂模式
- 外观模式
- 适配器模式
- 工厂方法模式
- 抽象工厂模式
- 生成器模式
- 原型模式
- 中介者模式
- 观察者模式
- 访问者模式
- 命令模式
- 网络编程
- epoll reactor模式
- linux timerfd系列函数总结
- IO
- mapreduce
- 反射器
- leo通信库
- Mutex
- Condition
- thread
- raft
- 协程
- hook
- 定时器
- 别人的面试经验
- 面试题
- vector崩溃问题
- JAVA
- Linux java环境配置
- ucore
- lab1
- FreeNOS
- leveldb
- 刷题笔记
- 回文串
- 前缀树
- 字符串查找
- 查找两个字符串a,b中的最长公共子串
- 动态规划
- golang
- 顺序循环打印实现
- 数据结构
- rpc运用
- python
- 单例
- 深拷贝浅拷贝
- 链表
- python基础题
- mysql
- 事务
- Linux
- 共享内存
- 刷题记录
- 贪心算法
- 动态规划
- 面试
- 腾讯C++面试
- 微众面试JD
- 迅雷网络面试
- 学习网址
- rabbitMq
