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. 实验结果