类反射的由来
类反射的由来
实现代码
反射类例子
调用例子
类反射的由来
标题想必搜到此篇文章的程序员们应该都知道为啥需要它了吧!在此呢我们就不做详细说明了,我的简单理解呢是可以通过“类名”反射出一个类对象。
最近呢在做项目的时候遇到了一堆数据交换,需要把数据反序列化给对象成员,常规做法呢是有多少种对象就多少个case去判断当前数据类型然后再通过指定对象去反序列化。
这种问题呢像在一些高级语言 如C#,JAVA中就比较好解决官方提供了较完善的反射机制,可惜了谁让我们用的是C++ 啥事都得自己来
一开始呢我也有网上查找C++相关的实现,但是感觉代码实在太多了,于是乎就自己写了个简单版本
实现的基本思想是:通过map映射把“类名”映射到创建类对象的函数指针,通过类名取得函数指针然后执行函数获得对象基类,从而通过虚函数去实现相关操作。
实现代码
主要还用到
C++11提供了对匿名函数的支持,称为Lambda函数(也叫Lambda表达式)
实现直接在插入的时候:函数指针直接用Lambda表达式
#pragma once
#include <string>
#include <map>
#include "CReflectBase.h"
//创建对象的函数指针
typedef CReflectBase* (*PF_CREATE_OBJECT)();
//类名创建对象
CReflectBase* ClassNameCreateObj(std::string _ClassName);
//把类名添加到map
#define ADD_CLASS_REGISTER(className) g_ReflectRegisterMap.insert(std::make_pair(#className, []() -> CReflectBase* {return new className; }))
//定义一个全局的map保存字符串到动态类生成的函数指针的映射表
std::map<std::string, PF_CREATE_OBJECT> g_ReflectRegisterMap;
class CReflectBase
{
public:
virtual void ShowTest() = 0;
};
class CA :public CReflectBase
{
public:
void ShowTest()
{
cout << "CA::ShowTest()\r\n";
}
};
class CB :public CReflectBase
{
public:
void ShowTest()
{
cout << "CB::ShowTest()\r\n";
}
};
inline void InitClassReflect()
{
//要反射的类必须添加
ADD_CLASS_REGISTER(CA);
ADD_CLASS_REGISTER(CB);
}
CReflectBase* ClassNameCreateObj(std::string _ClassName)
{
//先判断是否已经初始化,不支持线程安全,如果需要涉及,该初始化请放到主线程中或者加个临界锁
if (0 == g_ReflectRegisterMap.size())
{
InitClassReflect();
}
auto itr = g_ReflectRegisterMap.find(_ClassName);
if (itr != g_ReflectRegisterMap.end())
{
return ((PF_CREATE_OBJECT)itr->second)();
}
return nullptr;
}
int main()
{
auto obj = ClassNameCreateObj("CA");
if (nullptr != obj)
{
obj->ShowTest();
delete obj;
}
obj = ClassNameCreateObj("CB");
if (nullptr != obj)
{
obj->ShowTest();
delete obj;
}
return 0;
}