C++实现反射

1.前言

 反射:通过类的名字得到该类的实例对象

2. 思路

 1. 在需要反射的类中定义一个创建该类对象的回调函数(静态成员函数,这样不需创建出类对象即可调用)

 2. 设计一个工厂类,类中有一个map,用于保存类名和创建类实例的回调函数,该工厂类提供注册反射类和创建类实例的接口

 3. 初始化时,将需要反射类的名字和回调函数存入map里,类名字做为map的key值;回调函数作为map的value值

 4. 传入类的名字,调用工厂类的创建函数,得到需要的类实例指针

3. 实现

1. 步骤1中示例类的代码

CTest.h

#ifndef __CTEST_H
#define __CTEST_H

#include <iostream>
using namespace std;

class CTest
{
public:
	CTest();
	~CTest();
	
public:

	// 测试函数
	void print();

	// 创建实例的函数,静态函数,这样注册时不需要创建类实例
	static void* create_Test();
};

#endif

CTest.cpp

#include "CTest.h"

CTest::CTest()
{
	cout<<"call CTest Constructor fun"<<endl; 
}

CTest::~CTest()
{ 
	cout<<"call CTest Destructor fun"<<endl; 
}

void CTest::print()
{ 
	cout<<"call CTest print fun"<<endl; 
}

void* CTest::create_Test()
{
	CTest* PTest = new CTest();
	return PTest;
}

2. 步骤2中工厂类的代码

CClassFactory.h

#ifndef __CCLASSFACTORY_
#define __CCLASSFACTORY_

#include <iostream>
#include <map>
#include <string>

using namespace std;

// 创建类实例的函数指针
typedef void* (*create_fun)();

// 工厂类,提供注册反射类和创建类实例的接口
class CClassFactory
{
public:
	~CClassFactory();

	// 根据类名字创建类实例
	void* CreateClassEntity(string name);

	//注册类名称与指针函数到映射关系
	void RegistClass(string name, create_fun fun); 

	// 获取工厂,单例模式
	static CClassFactory& GetInstance();  
private:

	// 构造函数必须私有化,外部只可调用getInstance()来获取工厂对象
	CClassFactory();
	
	// key:类名,value:创建该类的回调函数
	map<string, create_fun> m_map;
}; 

#endif

CClassFactory.cpp

#include"CClassFactory.h"

CClassFactory::CClassFactory()
{
}

CClassFactory::~CClassFactory()
{
}

void* CClassFactory::CreateClassEntity(string name)
{
	map<string, create_fun>::iterator iter = m_map.find(name);
	if (iter == m_map.end()) 
	{ 
		return NULL; 
	}

	create_fun fun = iter->second;
	if (fun == NULL) 
	{ 
		return NULL; 
	}

	return fun();
}   

void CClassFactory::RegistClass(string name, create_fun fun)
{
	m_map[name] = fun;
}   

CClassFactory& CClassFactory::GetInstance()
{
	// 通过静态变量来实现单例模式,这样只有在调用本函数时才会进行工厂的初始化
	static CClassFactory fac;
	return fac;
} 

3. 步骤3中的初始化代码和步骤4中的调用代码

main.cpp

#include "CTest.h"
#include "CClassFactory.h"

int main()
{
	// 先注册
	CClassFactory::GetInstance().RegistClass("CTest", CTest::create_Test);	

	// 根据名字创建出类对象
	CTest* PTest = (CTest*)CClassFactory::GetInstance().CreateClassEntity("CTest");
	if (PTest == NULL)
	{
		cout<<"create CTest entity failed"<<endl;
		return -1;
	}   

	// 调用类对象的函数
	PTest->print();
	
	delete PTest;

	return 0;
}
4. 实验结果


猜你喜欢

转载自blog.csdn.net/yzf279533105/article/details/79780054
今日推荐