代码环境为VScode + CMake + GCC 8.1.0
首先,如何才能做到给我一个名字我就能拿到这个对象的这个值,也是比较难的一个地方,方法如下
#define OFFSET(className,fieldName) (size_t)&(((className*)0)->fieldName)
这个能够得到该成员变量与该对象的偏移量,之后根据这个偏移量来获取成员的值
正题开始
首先这个反射类应该只有一个,要不然反射就会变得很混乱,这一个反射对象,那里一个反射对象。所以应该将该反射类变为一个单例。全局内只允许出现一个。单例类如下:
Singleton.h
#pragma once #include "Singleton.h" #ifndef _SINGLETON_ #define _SINGLETON_ #include "Util.h" NAME_SPACE_START(myUtil) //单例模式 template class Singleton{ public: static T* Instance(){ if(m_instance==nullptr){ m_instance = new T(); } return m_instance; } private: Singleton(); Singleton(const Singleton&); ~Singleton(); Singleton& operator=(const Singleton&); private: static T* m_instance; }; template T* Singleton::m_instance=nullptr; #define SINGLETON_DECLARE(className) \ friend class Singleton; \ className(){}; \ className(const className&){}; \ ~className(){}; \ className& operator=(const className&); NAME_SPACE_END() #endif //!_SINGLETON_
我在这个头文件中写了一个单例声明SINGLETON_DECLARE,只要将这个声明放到私有部分就行了,这个类就变为一个单例类了。
反射类
如何才能做到反射呢,应该在这个反射类中保存注册表,传入了对应的类名,返回对应的信息,然后使用基类实现对应的方法即可。代码如下:
Reflex.h
#pragma once #include "Util.h" #include #include #include #include #ifndef _REFLEX_ #define _REFLEX_ NAME_SPACE_START(myUtil) #include "Singleton.h" #include
该反射类使用方法如下:
#include #include #include "Util.h" #include "Singleton.h" #include "Reflex.h" using namespace std; using namespace myUtil; class A:public RObject{ public: void show(){ cout<<"hello world"<::Instance(); A* a=(A*)factory->createClass("A"); cout<get("m_age")<set("m_age", 30); cout << a->get("m_age") << endl; a->Call("show"); int b = a->Call("add",1,5); cout << b << endl; A* c=(A*)factory->createClass("A"); cout<get("m_age")<set("m_age", 40); cout << c->get("m_age") << endl; c->Call("show"); b = c->Call("add",2,5); cout << b << endl; return 0; }
结果截图
最后讲解一下是怎么用的,见注释
//首先要使用反射的类要继承RObject //要使用反射的类和成员方法都要声明为public class A:public RObject{ public: void show(){ cout<<"hello world"<::Instance(); A* a=(A*)factory->createClass("A"); //为了能够得到准确的类型值,这里使用模板来获取 cout<get("m_age")<set("m_age", 30); cout << a->get("m_age") << endl; //调用无参且无返回值的成员函数时使用没有模板的Call,反之使用有模板的Call a->Call("show"); int b = a->Call("add",1,5); cout << b << endl; return 0; }
到此这篇关于详解如何利用C++实现一个反射类的文章就介绍到这了,更多相关C++反射类内容请搜索0133技术站以前的文章或继续浏览下面的相关文章希望大家以后多多支持0133技术站!