lee-romantic 's Blog
Everything is OK!
Toggle navigation
lee-romantic 's Blog
主页
About Me
归档
标签
C++ 部分反射功能的实现(通过字符串获取对象)
2022-12-01 17:50:45
37
0
0
lee-romantic
# 问题 反射,即Reflection,是很多高级编程语言的一种十分强大的特性,比如Java,可以于运行时加载、探知、使用编译期间完全未知的classes。而C++是天然不支持反射的,但是可以通过一些特殊手段实现类似反射的效果,本文对使用字符串创建对象,稍作探讨。 # 目标 我们要实现的目标是要通过字符串创建对象,即下面的代码: ``` ClassT* obj = FactoryCreate("ClassT"); ``` 但是我们要知道,这并不是完全意义上的反射,因为不能取到对象的属性和值,所以只是伪反射。 # 实现 - 基本思路就是,声明要继承的基类BaseClass,BaseClass就是给用户继承使用类,并且其可以声明为任意类型,并通过宏定义REGISTER进行工厂模式注册构造函数。 - 工厂Factory中通过map关联字符串和构造函数。最后,我们就可以通过类名字符串,在map中找到相应的构造函数,从而获取到(或者构建)字符串对应的用户自定义类的对象。 ``` // // Created by libo on 2022/11/30. // #include <map> #include <string> #include <iostream> #define REGISTER(className) \ className* objectCreator##className(){ \ return new (className); \ } \ RegisterAction g_creatorRegister##className( \ #className, (constrFuncPtr)objectCreator##className); class BaseClass{ public: virtual void m_print(){ std::cout<<"hello BaseClass"<<std::endl; }; }; // constructed function pointer typedef BaseClass*(*constrFuncPtr)(); class ClassFactory { private: std::map<std::string, constrFuncPtr> m_classMap ; ClassFactory()= default;; ~ClassFactory()= default;; public: BaseClass* getClassByName(const std::string& className); void registClass(const std::string& name, constrFuncPtr createPtr); static ClassFactory& getInstance() ; }; BaseClass* ClassFactory::getClassByName(const std::string& className){ std::map<std::string, constrFuncPtr>::const_iterator iter; iter = m_classMap.find(className) ; if ( iter == m_classMap.end() ) return nullptr; else return (*iter->second)(); } void ClassFactory::registClass(const std::string& name, constrFuncPtr createPtr) { m_classMap.insert(std::pair<std::string, constrFuncPtr>(name, createPtr)); } ClassFactory& ClassFactory::getInstance(){ static ClassFactory sLo_factory; return sLo_factory ; } class RegisterAction{ public: RegisterAction(std::string className, constrFuncPtr createPtr){ ClassFactory::getInstance().registClass(std::move(className), createPtr); } }; // Derived class class ClientClass : public BaseClass { public: void m_print() override{ std::cout<<"hello ClientClass"<<std::endl; }; }; class Client2Class : public ClientClass { public: void m_print() override{ std::cout<<"hello Client2Class"<<std::endl; }; }; REGISTER(BaseClass); REGISTER(ClientClass); REGISTER(Client2Class); int main(int argc,char* argv[]) { BaseClass* ptrObj= ClassFactory::getInstance().getClassByName("ClientClass"); if(!ptrObj) { std::cout<< "ptrObj is nullptr! exit!" << std::endl; return 0; } ptrObj->m_print(); return 0; } ``` # 参考 https://blog.csdn.net/y1196645376/article/details/51455273 https://blog.csdn.net/ddllrrbb/article/details/88784330
上一篇:
C++ 左值右值、移动语义、完美转发
下一篇:
基于CMake构建动(静)态库项目
0
赞
37 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册