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