C++反射方法[转]
前段时间看设计模式看到C#里面是通过assmeble的方法,知道函数名,然后调用函数,今天突然想到这个事情,然后百度了下,看看C++下面是怎么办的,要写狗屁论文所以没细看,先mark一下。
C++反射方法【转】http://blog.csdn.net/wrq147/article/details/5603262
众所周知C++语言本身是没有反射这个东东的,但C++的强大之处在于它把不能的化为可能。
要实现反射主要就几点问题:
1、每个要反射的类里定义一个回调函数(用来创建这个类实例)
2、在程序开始时把每个要反射的类的回调函数以类名为键存入全局哈希表
第一个问题我们使用继承就可以为每个类添加回调了
第二个问题我们知道程序开始时都会先初始化类的静态成员
现在看看我们要有一个类用来注册和获取类
#include <stdafx.h>
#include <string>
#include <map>
#include <iostream>
using namespace std;
typedef void* (*CreateFuntion)(void);//回调函数指针
/*
以下为工厂类,用来创建类和注册类
*/
class ClassFactory
{
public:
static void* GetClassByName(std::string name)
{
std::map<std::string,CreateFuntion>::const_iterator find;
find=m_clsMap.find(name);
if(find==m_clsMap.end())
{
return NULL;
}
else
{
return find->second();
}
}
static void RegistClass(std::string name,CreateFuntion method)
{
m_clsMap.insert(std::make_pair(name,method));
}
private:
static std::map<std::string,CreateFuntion> m_clsMap;
};
std::map<std::string,CreateFuntion> ClassFactory::m_clsMap;
我们还需要一个类包含回调函数和静态变量
template<class T,const char name[]>
class Register
{
public:
Register()
{
//这个一定要加,因为编译器不保证程序开始时就初始化变量rc
const RegistyClass tmp=rc;
}
static void* CreateInstance()
{
return new T;
}
public:
static const RegistyClass rc;
};
template<class T,const char name[]>
const RegistyClass Register<T,name>::rc(name,Register<T,name>::CreateInstance);
这里我们用宏来定义要反射的类会更方便
#define DEFINE_CLASS(class_name) /
char NameArray##class_name[]=#class_name;/
class class_name:public Register<class_name,NameArray##class_name>
#define DEFINE_CLASS_EX(class_name,father_class) /
char NameArray##class_name[]=#class_name;/
class class_name:public Register<class_name,NameArray##class_name>,public father_class
可以看到还需要一个RegistyClass 类来进行变量初始化并注册反射类
class RegistyClass
{
public:
RegistyClass(std::string name,CreateFuntion method)
{
ClassFactory::RegistClass(name,method);
}
};
最后的代码就是如下了
#include <stdafx.h>
#include <string>
#include <map>
#include <iostream>
using namespace std;
typedef void* (*CreateFuntion)(void);
/*
以下为工厂类,用来创建类和注册类
*/
class ClassFactory
{
public:
static void* GetClassByName(std::string name)
{
std::map<std::string,CreateFuntion>::const_iterator find;
find=m_clsMap.find(name);
if(find==m_clsMap.end())
{
return NULL;
}
else
{
return find->second();
}
}
static void RegistClass(std::string name,CreateFuntion method)
{
m_clsMap.insert(std::make_pair(name,method));
}
private:
static std::map<std::string,CreateFuntion> m_clsMap;
};
std::map<std::string,CreateFuntion> ClassFactory::m_clsMap;
class RegistyClass
{
public:
RegistyClass(std::string name,CreateFuntion method)
{
ClassFactory::RegistClass(name,method);
}
};
template<class T,const char name[]>
class Register
{
public:
Register()
{
//这个一定要加,因为编译器不保证程序开始时就初始化变量rc
const RegistyClass tmp=rc;
}
static void* CreateInstance()
{
return new T;
}
public:
static const RegistyClass rc;
};
template<class T,const char name[]>
const RegistyClass Register<T,name>::rc(name,Register<T,name>::CreateInstance);
#define DEFINE_CLASS(class_name) /
char NameArray[]=#class_name;/
class class_name:public Register<class_name,NameArray>
#define DEFINE_CLASS_EX(class_name,father_class) /
char NameArray[]=#class_name;/
class class_name:public Register<class_name,NameArray>,public father_class
DEFINE_CLASS(CG)
{
public:
void Display()
{
printf("fff");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CG* tmp=(CG*)ClassFactory::GetClassByName("CG");
tmp->Display();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?