之前碰到过一个问题,C++中如何通过一个字符串生成一个类。
C++是不支持通过类名称字符串”ClassXX”来生成对象的,也就是说我们可以使用 new ClassXX
来生成对象,但是不能通过 new "ClassXX";
来生成对象。
我们就可以通过反射来解决这个问题,但是C++本身不支持反射,却可以让我们自己实现。
设计思路:
(1)如果需要实现字字符串到函数到映射,一定要使用到函数指针
(2)可以使用map保存字符从到函数指针到映射。
(3)工厂类提供字符串与函数指针到注册关系。
(4)程序开始运行时,将回调函数存入std::map(哈希表)里面,类名字做为map的key值。
代码如下:
class_factory.h
#ifndef __CLASSFACTORY_ #define __CLASSFACTORY_ #include <iostream> #include<string> #include<map> //定义函数指针 typedef void* (*create_fun)(); class ClassFactory{ public: ~ClassFactory() {}; //根据类注册时的名字, 创建类实例, 并返回 void* getClassByName(std::string name){ std::map<std::string, create_fun>::iterator it = my_map.find(name); if (it == my_map.end()) { return NULL; } create_fun fun = it->second; if (!fun) { return NULL; } return fun(); } //注册类名称与指针函数到映射关系 void registClass(std::string name, create_fun fun){ my_map[name] = fun; } //单例模式 static ClassFactory& getInstance(){ static ClassFactory fac; return fac; } private: ClassFactory() {}; //私有 std::map<std::string, create_fun> my_map; }; #endif
test.h
#ifndef __TEST_H #define __TEST_H #include <iostream> class Test{ public: Test(){ std::cout << "call Test Constructor fun" << std::endl; } ~Test(){ std::cout << "call Test Destructor fun" << std::endl; } void print(){ std::cout << "call Test print fun" << std::endl; } }; void* create_Test(){ Test *t = new Test; return (t == NULL)? NULL:t; } #endif
main.cpp
#include "test.h"#include "ClassFactory.h" int main(){ //注册 ClassFactory::getInstance().registClass("Test", create_Test); //获取类对象 Test *t = (Test*)ClassFactory::getInstance().getClassByName("Test"); if (!t){ std::cout << "get instnce Test err;" << std::endl; return 1; } t->print(); delete t; return 0; }
部分引用:https://www.cnblogs.com/xudong-bupt/p/6643721.html