版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HQ354974212/article/details/85015132
JAVA,C# 中都具有反射机制,但是C++没有语法支持,但是可以自己实现,来通过字符串产生对象,其实仅仅是个语法糖而已
实现思路:
ClassFactory类的一个map 存储 key 相应的类名 和 value 创建该类对象的函数地址 , ClassFactory类提供CreateObjectByName方法创建该类的对象:这个方法的本质就是调用map中存储的函数地址来调用对应得的函数。
RegisterAction类,实际上没什么用,只是在构造函数中把 key,value加入到ClassFactory的map中去,所以需要定义一个对象来执行构造函数,为了简化定义了REGISTER宏
框架层:
使用基类指针接收派生类对象的指针: ClassFactory::getInstance().CreateObjectByName("ClassA") 可产生派生类对象, 这里的类名,完全可以从配置文件读取。
用户层:
class 派生类 :public Base
{
public:
......
static 派生类 * CreateObjec()
{
return new 派生类;
}
};
REGISTER(派生类)
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef void* (*PCreateObject)(void);
class ClassFactory
{
private:
map<string, PCreateObject> m_classMap;
ClassFactory() {};
public:
void* CreateObjectByName(string className)
{
map<string, PCreateObject>::const_iterator iter;
iter = m_classMap.find(className);
if (iter == m_classMap.end())
return NULL;
else
return iter->second(); //函数指针的调用
}
void registClass(string name, PCreateObject method)
{
m_classMap.insert(pair<string, PCreateObject>(name, method));
}
static ClassFactory& getInstance()
{
{
static ClassFactory cf;
return cf;
}
}
};
class RegisterAction {
public:
RegisterAction(string className, PCreateObject ptrCreateFn) {
ClassFactory::getInstance().registClass(className, ptrCreateFn);
}
};
//定义全局函数创建该类的对象, 并且定义一个全局对象来初始化注册流程
#define REGISTER(className) RegisterAction g_RegisterAction##className(#className,(PCreateObject)className##::CreateObjec);
class Base
{
public :
virtual void print() = 0;
};
class ClassA :public Base
{
public:
void print()
{
cout << "Print ClassA" << endl;
}
static ClassA * CreateObjec()
{
return new ClassA;
}
};
REGISTER(ClassA)
class ClassB :public Base
{
public:
void print()
{
cout << "Print ClassB" << endl;
}
static ClassB * CreateObjec()
{
return new ClassB;
}
};
REGISTER(ClassB)
int main()
{
Base *p = NULL;
p= (Base *)ClassFactory::getInstance().CreateObjectByName("ClassA");
p->print();
p = (Base *)ClassFactory::getInstance().CreateObjectByName("ClassB");
p->print();
}
运行效果图