C++实现反射(利用字符串创建对象)

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();
}

  

运行效果图

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页