1.前言
反射:通过类的名字得到该类的实例对象
2. 思路
1. 在需要反射的类中定义一个创建该类对象的回调函数(静态成员函数,这样不需创建出类对象即可调用)
2. 设计一个工厂类,类中有一个map,用于保存类名和创建类实例的回调函数,该工厂类提供注册反射类和创建类实例的接口
3. 初始化时,将需要反射类的名字和回调函数存入map里,类名字做为map的key值;回调函数作为map的value值
4. 传入类的名字,调用工厂类的创建函数,得到需要的类实例指针
3. 实现
1. 步骤1中示例类的代码
CTest.h
#ifndef __CTEST_H #define __CTEST_H #include <iostream> using namespace std; class CTest { public: CTest(); ~CTest(); public: // 测试函数 void print(); // 创建实例的函数,静态函数,这样注册时不需要创建类实例 static void* create_Test(); }; #endif
CTest.cpp
#include "CTest.h" CTest::CTest() { cout<<"call CTest Constructor fun"<<endl; } CTest::~CTest() { cout<<"call CTest Destructor fun"<<endl; } void CTest::print() { cout<<"call CTest print fun"<<endl; } void* CTest::create_Test() { CTest* PTest = new CTest(); return PTest; }
2. 步骤2中工厂类的代码
CClassFactory.h
#ifndef __CCLASSFACTORY_ #define __CCLASSFACTORY_ #include <iostream> #include <map> #include <string> using namespace std; // 创建类实例的函数指针 typedef void* (*create_fun)(); // 工厂类,提供注册反射类和创建类实例的接口 class CClassFactory { public: ~CClassFactory(); // 根据类名字创建类实例 void* CreateClassEntity(string name); //注册类名称与指针函数到映射关系 void RegistClass(string name, create_fun fun); // 获取工厂,单例模式 static CClassFactory& GetInstance(); private: // 构造函数必须私有化,外部只可调用getInstance()来获取工厂对象 CClassFactory(); // key:类名,value:创建该类的回调函数 map<string, create_fun> m_map; }; #endif
CClassFactory.cpp
#include"CClassFactory.h" CClassFactory::CClassFactory() { } CClassFactory::~CClassFactory() { } void* CClassFactory::CreateClassEntity(string name) { map<string, create_fun>::iterator iter = m_map.find(name); if (iter == m_map.end()) { return NULL; } create_fun fun = iter->second; if (fun == NULL) { return NULL; } return fun(); } void CClassFactory::RegistClass(string name, create_fun fun) { m_map[name] = fun; } CClassFactory& CClassFactory::GetInstance() { // 通过静态变量来实现单例模式,这样只有在调用本函数时才会进行工厂的初始化 static CClassFactory fac; return fac; }
3. 步骤3中的初始化代码和步骤4中的调用代码
main.cpp
#include "CTest.h" #include "CClassFactory.h" int main() { // 先注册 CClassFactory::GetInstance().RegistClass("CTest", CTest::create_Test); // 根据名字创建出类对象 CTest* PTest = (CTest*)CClassFactory::GetInstance().CreateClassEntity("CTest"); if (PTest == NULL) { cout<<"create CTest entity failed"<<endl; return -1; } // 调用类对象的函数 PTest->print(); delete PTest; return 0; }4. 实验结果