2.工厂模式结合回调机制。
首先我们要梳理一下这个方法的基本脉络:
1.工厂内部需要有个映射,也就是一个字符串对应一个类new的方法。
2.工厂给出一个接口,我们传入字符串,那么返回这个字符串对应的方法new出来的对象指针。
3.我们新建的类,如果需要支持反射机制,那么这个类需要自动将自己的new方法和名字注册到工厂的映射中。
OK,如果我们能完成以上几个要求,那么我们在类进行拓展的时候需要改动的地方就十分少了。对于工厂的代码我们基本上是不会改变的。也就基本上实现了我们C++反射机制的基本功能。
下面我们来一步一步解析代码:
首先我们还是需要一个Object作为需要支持反射机制类的基类
//Reflex.h
class Object
{
public:
Object(){}
virtual ~Object(){}
static bool Register(ClassInfo* ci); //注册传入一个classInfo(类信息),将这个类的信息注册到映射中
static Object* CreateObject(string name); //工厂生产对象的接口
};
然后是实现:
//Reflex.cpp
static std::map< string, ClassInfo*> *classInfoMap = NULL;
bool Object::Register(ClassInfo* ci)
{
if (!classInfoMap) {
classInfoMap = new std::map< string, ClassInfo*>(); //这里我们是通过map来存储这个映射的。
}
if (ci) {
if (classInfoMap->find(ci->m_className) == classInfoMap->end()){
classInfoMap->insert(std::map< string, ClassInfo*>::value_type(ci->m_className, ci)); // 类名 <-> classInfo
}
}
return true;
}
Object* Object::CreateObject(std::string name)
{
std::map< string, ClassInfo*>::const_iterator iter = classInfoMap->find(name);
if (classInfoMap->end() != iter) {
return iter->second->CreateObject(); //当传入字符串name后,通过name找到info,然后调用对应的CreatObject()即可
}
return NULL;
}
剩下的我们还需要一个classinfo类就大功告成了:
//Reflex.h
typedef Object* (*ObjectConstructorFn)(void);
class ClassInfo
{
public:
ClassInfo(const std::string className, ObjectConstructorFn ctor)
:m_className(className), m_objectConstructor(ctor)
{
Object::Register(this); //classInfo的构造函数是传入类名和类对应的new函数然后自动注册进map中。
}
virtual ~ClassInfo(){}
Object* CreateObject()const { return m_objectConstructor ? (*m_objectConstructor)() : 0; }
bool IsDynamic()const { return NULL != m_objectConstructor; }
const std::string GetClassName()const { return m_className; }
ObjectConstructorFn GetConstructor()const{ return m_objectConstructor; }
public:
string m_className;
ObjectConstructorFn m_objectConstructor;
};
有了这些类后,我们只需要让需要支持反射的类满足以下要求即可:










