C++实现反射机制

C++是不支持通过类名称字符串”ClassXX”来生成对象的,也就是说我们可以使用
ClassXX* object =new ClassXX; 来生成对象,
但是不能通过ClassXX* object=new “ClassXX”; 来生成对象。
反射是一种通过程序运行过程中用类名创建对象,并获取类的成员和方法。
Factory.h

#ifndef _FACTORY_H
#define _FACTORY_H

#include<iostream>
using namespace std;
#include<map>
#include<string>
typedef void* (*create_fun)();

#define REGISTER(className)                                             \
    className* objectCreator##className(){                              \
        return new className;                                           \
    }                                                                   \
    RegisterAction g_creatorRegister##className(                        \
        #className,(create_fun)objectCreator##className)

class Factory
{
public:
	~Factory(){}
	void *GetClassByName(string name)
	{
		std::map<string,create_fun>::iterator ite = my_class.find(name);
		if(ite==my_class.end())
			return NULL;
		else
			return ite->second();
	}
	void RegisterClass(string name,create_fun fun)
	{
		my_class[name]=fun;
	}
	static Factory& GetInstance()
	{
		static Factory f;
		return f;
	}
private:
	Factory(){}
	std::map<string,create_fun> my_class;
};


#endif

test.h

#ifndef __TEST_H
#define __TEST_H

#include <iostream>
using namespace std;
class Test{
public:
    Test()
	{ 
		cout << "call Test Constructor fun" << endl; 
	}
    ~Test()
	{ 
		cout << "call Test Destructor fun" << endl; 
	}
    void print()
	{ 
		cout << "call Test print fun" << endl; 
	}
};

class RegisterAction{
public:
	RegisterAction(string className,create_fun ptrCreateFn){
		Factory::GetInstance().RegisterClass(className,ptrCreateFn);
    }
};

#endif

main.h

#include"Factory.h"
#include"test.h"

REGISTER(Test);
int main()
{
	Test *t = (Test*)Factory::GetInstance().GetClassByName("Test");
	if(!t)
	{
		cout<<"get class error"<<endl;
		return 0;
	}
	else
		t->print();
	delete t;
	system("pause");
	return 0;
}

疑问

我们在通过类名称字符串创建类实例的时候,我们还是需要用到类名进行强制类型转换,有了类名称,我们何必还要处心积虑实现反射的功能呢,直接用类名创建实例不就行了么?

上面实现的反射只是了基本的反射问题。还有一种应用场景就是我们定义好了基类,给客户继承,但是我们并不知道客户继承基类后的类型名称。我们可以通过配置文件说明客户实现的具体类型名称,这样我们就可以通过类名称字符串来创建客户自定义类的实例了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值