众所周知C++语言本身是没有反射这个东东的,但C++的强大之处在于它把不能的化为可能。
要实现反射主要有以下两点问题:
1、每个要反射的类里定义一个回调函数(用来创建这个类实例)
2、在程序开始时把每个要反射的类的回调函数以类名为键存入全局哈希表
(1)首先要有一个类用来注册和获取类
/*******classfactory.h********/
#include <stdafx.h>
#include <string>
#include <map>
#include <iostream>
using namespace std;
typedef void* (*CreateFuntion)(void);//回调函数指针
class ClassFactory
{
public:
static void* GetClassByName(std::string name)
{
std::map<std::string,CreateFuntion>::const_iterator find;
find=m_clsMap.find(name);
if(find==m_clsMap.end())
{
return NULL;
}
else
{
return find->second();
}
}
void RegistClass(std::string name,CreateFuntion method)
private:
static std::map<std::string,CreateFuntion> m_clsMap;
};
/***********************************************/
/*************classfactory.cpp******************/
std::map<std::string,CreateFuntion> ClassFactory::m_clsMap;
void RegistClass(std::string name,CreateFuntion method)
{
m_clsMap.insert(std::make_pair(name,method));
}
/**************************************************/
(2)其次还需要一个类包含回调函数和静态变量
/*************register.h**********************/
template<class T,const char name[]>
class Register
{
public:
Register()
{
//这个一定要加,因为编译器不保证程序开始时就初始化变量rc
const RegistyClass tmp=rc;
}
static void* CreateInstance()
{
return new T;
}
public:
static const RegistyClass rc;
};
template<class T,const char name[]>
const RegistyClass Register<T,name>::rc(name,Register<T,name>::CreateInstance);
/**********************************************/
(3)再次,看到还需要一个RegistyClass 类来进行变量初始化并注册反射类
/*******************registyclass.h***************************/
class RegistyClass
{
public:
RegistyClass(std::string name,CreateFuntion method)
{
ClassFactory::RegistClass(name,method);
}
};
/****************************************************************/
(4)最后用宏来定义要反射的类会更方便
#define DEFINE_CLASS(class_name) /
char NameArray##class_name[]=#class_name;/
class class_name:public Register<class_name,NameArray##class_name>
#define DEFINE_CLASS_EX(class_name,father_class) /
char NameArray##class_name[]=#class_name;/
class class_name:public Register<class_name,NameArray##class_name>,public father_class