C++如何实现伪反射!
2017-08-26 12:33
218 查看
博主在写程序时遇到了需要运用XML根据类名去动态的创建类对象的问题。这个方式在拥有反射机制的语言中很好实现,例如JAVA,但是C++没有反射机制。不过强大的C++允许我们自己实现伪反射。
下面上博主自己写的一个实现伪反射的C++代码:
ClassFactory.h
ClassFactory.cpp
如此便实现了伪反射。
下面博主带大家分析代码。
首先博主为大家讲解实现思想,大家可以参考上面的整体代码来看下面的局部代码,以下代码只放出声明用于讲解思想,想知道实现请看上面的ClassFactory.cpp。
1.写一个类,这个类中有一个私有的键值对数据,用于存储你需要创建的类对象的类名以及创建该类对象的函数指针。如此我们便可以根据类名去动态的创建类对象了!
2.我们需要再写一个类用于将你需要创建的类对象的类名以及创建该类对象的函数指针存储进键值对中。
3.因为我们每一个类都应该有一个创建该类对象的函数,并有一个函数指针指向该函数,并且将这个类的类名与该函数指针添加到键值对中。在编程中重复是大忌,因为每个类都要进行此操作,因此,博主将其抽象出来运用宏去解决。
如此便完成了思想的讲解。
那么大家应该如何使用博主写的库文件呢?
大家只需要在自己的工程中添加博主的ClassFactory.h和ClassFactory.cpp文件。然后在自己需要根据类名动态创建的类的实现.cpp文件中后写上REGISTER(类名)就可以了,例如:
然后在实际运用中只需要从XML中提取出类名就可以动态的创建类对象啦!如下代码所示:(博主在这里使用的是tinyXML2解析库。)
是不是很简单呢?有帮助的话点个赞吧!有问题的话欢迎大家在评论区批评指正。
下面上博主自己写的一个实现伪反射的C++代码:
ClassFactory.h
#pragma once #include <map> #include <iostream> #include <string> using namespace std; #define REGISTER(ClassName) \ ClassName* ObjectCreator##ClassName(){ \ return new ClassName; \ } \ RegisterAction CreatorRegister##ClassName( \ #ClassName,(CreateObject)ObjectCreator##ClassName) typedef void* (*CreateObject)(void); //函数指针 class ClassFactory { private: map<string, CreateObject> m_classMap ; ClassFactory(){}; //构造函数私有化 public: void* GetClassByName(string className); void RegistClass(string name, CreateObject method) ; static ClassFactory& GetInstance() ; }; class RegisterAction { public: RegisterAction(string ClassName,CreateObject CreateOb) { ClassFactory::GetInstance().RegistClass(ClassName,CreateOb); } };
ClassFactory.cpp
#include "ClassFactory.h" void* ClassFactory::GetClassByName(string ClassName) { map<string, CreateObject>::const_iterator iter = m_classMap.find(ClassName); if ( iter == m_classMap.end() ) { return NULL ; } else { return iter->second() ; } } void ClassFactory::RegistClass(string name, CreateObject method) { m_classMap.insert(pair<string, CreateObject>(name, method)) ; } ClassFactory& ClassFactory::GetInstance() { static ClassFactory sLo_factory; return sLo_factory ; }
如此便实现了伪反射。
下面博主带大家分析代码。
首先博主为大家讲解实现思想,大家可以参考上面的整体代码来看下面的局部代码,以下代码只放出声明用于讲解思想,想知道实现请看上面的ClassFactory.cpp。
1.写一个类,这个类中有一个私有的键值对数据,用于存储你需要创建的类对象的类名以及创建该类对象的函数指针。如此我们便可以根据类名去动态的创建类对象了!
class ClassFactory { private: map<string, CreateObject> m_classMap ; ClassFactory(){}; //构造函数私有化 public: void* GetClassByName(string className); void RegistClass(string name, CreateObject method) ; static ClassFactory& GetInstance() ; };
2.我们需要再写一个类用于将你需要创建的类对象的类名以及创建该类对象的函数指针存储进键值对中。
class RegisterAction { public: RegisterAction(string ClassName,CreateObject CreateOb) { ClassFactory::GetInstance().RegistClass(ClassName,CreateOb); } };
3.因为我们每一个类都应该有一个创建该类对象的函数,并有一个函数指针指向该函数,并且将这个类的类名与该函数指针添加到键值对中。在编程中重复是大忌,因为每个类都要进行此操作,因此,博主将其抽象出来运用宏去解决。
#define REGISTER(ClassName) \ ClassName* ObjectCreator##ClassName(){ \ return new ClassName; \ } \ RegisterAction CreatorRegister##ClassName( \ #ClassName,(CreateObject)ObjectCreator##ClassName) typedef void* (*CreateObject)(void); //函数指针
如此便完成了思想的讲解。
那么大家应该如何使用博主写的库文件呢?
大家只需要在自己的工程中添加博主的ClassFactory.h和ClassFactory.cpp文件。然后在自己需要根据类名动态创建的类的实现.cpp文件中后写上REGISTER(类名)就可以了,例如:
#include "CTriangle.h" int CTriangle::show() { cout << " " << endl; return 0; } REGISTER(CTriangle);
然后在实际运用中只需要从XML中提取出类名就可以动态的创建类对象啦!如下代码所示:(博主在这里使用的是tinyXML2解析库。)
int ClassPrint() { list<CShape*> temp; tinyxml2::XMLDocument doc; if(doc.LoadFile("ClassXML.xml") != 0) { cout << "加载XML文件失败" << endl; system("pause"); exit(0); } tinyxml2::XMLElement* root = doc.RootElement(); tinyxml2::XMLElement* RSquare = root->FirstChildElement(); while(RSquare) { CShape* PCShape = (CShape*)ClassFactory::GetInstance().GetClassByName(RSquare->GetText()); if(PCShape != NULL) { temp.push_back(PCShape); } RSquare = RSquare->NextSiblingElement(); } return 0; }
是不是很简单呢?有帮助的话点个赞吧!有问题的话欢迎大家在评论区批评指正。
相关文章推荐
- C++ 如何用宏实现反射机制
- object c++如何实现反射机制
- object c++如何实现反射机制
- C++中如何实现类似JAVA中的反射
- object c++如何实现反射机制
- 如何使用反射技术实现ASP.NET国际化站点
- c++中如何用string实现CString格式化的功能
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- 在c++中如何实现非consle类型的计时器
- C/C++面试之算法系列--如何实现用更少的空间表示英文字母(a ~ z)构成char A[n]字符串
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- (vc++ 98版的 xp) C++如何实现ring0
- 如何在C和C++中实现回调
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- 如何在C++中实现类似Scanf的变参个数函数
- prjShutDownPC - 如何实现关机/重启/注销 - SourceCode - C++ & API & MFC - HackerJLY
- c++ 如何实现多态
- 如何实现返回记录集的 Visual C++ COM 对象
- 引用(C++里的藿香正气)的真相-(VC编译器如何实现引用规则)
- 高质量c++(如何在派生类中实现类的基本函数)