概念

简而言之,反射就是对象类型在编译期是未知的,在运行期动态的创建的,通过名字获取该类的一个实例。

  1. class Person {
  2. public:
  3. virtual void show() = 0;
  4. }
  5. class Allen : public Person {
  6. virtual void show() {
  7. std::cout << "Hello, I'm Allen!" << std::endl;
  8. }
  9. }
  10. Person *p = new Allen();
  11. p->show();

首先获取对象
std::string className = /从配置文件中读取/
*p = getNewInstance(className);

C++实现发射方案 —— 对象工厂

对象工厂是一种可以间接实例化对象的类。

  1. class ObjectFactory{
  2. virtual ReflectObject* newInstance() = 0;
  3. }
  4. class ObjectFactory_Allen : public ObjectFactory{
  5. ReflectObject* newInstance(){
  6. // 这里注意一点就是,所有能够被反射的类都继承自 ReflectObject 这个类。
  7. return new Allen();
  8. };
  9. }

通过对象工厂构造具体的对象

  1. ObjectFactory *of = new ObjectFactory_Allen();
  2. // 有了对象工厂的实例后,就可以产生 Allen 对象的实例了
  3. ReflectObject *allen= of->newInstance();
  4. // 接下来可以使用类型转换,把 allen 对象转换成 Person
  5. Person *p = dynamic_cast<Person*>(allen);

反射器

反射器实际上也是一个类,它管理了类名到对象工厂实例之间的映射关系。反射器对象在程序中是一个全局唯一的对象。这种映射关系看起来就像一张表:
(“Allen”, Allen 的对象工厂的实例对象);
(“Luffy”, Luffy 的对象工厂的实例对象);
(“Zoro”, Zoro 的对象工厂的实例对象);

只要未来你想要编写一个新的类,比如 Bob 类,那么你就必须要同时编写 Allen 的工厂类 ObjectFactory_Bob,同时,你还得实例化一个这个工厂类的对象 objectFactory_Bob = new ObjectFactory_Bob(),并将 (“Bob”, objectFactory_Bob) 这种映射关系保存到反射器中。

  1. class Reflector
  2. {
  3. public:
  4. Reflector();
  5. ~Reflector();
  6. // 如果你要反射你的类,就必须将你的类名,以及工厂实例对象注册到反射器中。
  7. void registerFactory(const std::string& className, ObjectFactory *of);
  8. // 反射器可以根据对象工厂实例来生产实例对象。请参考 2.2 节
  9. ReflectObject* getNewInstance(const std::string& className);
  10. private:
  11. std::map<std::string, ObjectFactory*> objectFactories;
  12. };

开发流程:

  • 编写一个类继承ReflectObject类
  • 编写一个对应的工厂类,并实例化一个工厂类对象
  • 调用反射器的registerFactory接口,讲类名和工厂类对象注册掉反射器

    demo:

    第一步: 定义一个allen类 ```cpp class ReflectObject{ }

class allen : public ReflectObject{ }

  1. 第二步: 定义allen类对应的工厂类<br />
  2. ```cpp
  3. class ObjectFactory{
  4. virtual ReflectObject* newInstance() = 0;
  5. }
  6. class ObjectFactory_Allen : public ObjectFactory{
  7. ReflectObject* newInstance(){
  8. return new Allen();
  9. };
  10. }

第三步: 创建工厂类对象,注册到反射器中

  1. // 函数 reflector 可以用来获取反射器对象。
  2. reflector().registerFactory("Allen", new ObjectFactory_Allen());

第四步: 使用时获取allen类对象

  1. Person *allen = getNewInstance<Person>("Allen");

宏定义实现反射

  1. /***********需要被反射的类,需要在其对应的 cpp 文件中进行反射声明***********/
  2. #define REFLECT(name)\
  3. class ObjectFactory_##name : public ObjectFactory{\
  4. public:\
  5. ReflectObject* newInstance() {\
  6. return new name(); \
  7. }\
  8. }; \
  9. class Register_##name{\
  10. public:\
  11. Register_##name(){\
  12. reflector().registerFactory(#name, new ObjectFactory_##name()); \
  13. }\
  14. };\
  15. Register_##name register_##name;

这样的话, demo的第二三步可以简化为:

  1. REFLECT(Allen);

完整示例:

反射器类具体代码

  1. // Reflect.h
  2. #pragma once
  3. #include <string>
  4. #include <map>
  5. #include <iostream>
  6. /********************所有需要实现反射的类需要继承它************************/
  7. class ReflectObject {
  8. public:
  9. virtual ~ReflectObject(){}
  10. };
  11. /************************************************************************/
  12. /******************对象工厂抽象类,用来生成对象实例************************/
  13. class ObjectFactory {
  14. public:
  15. ObjectFactory(){ std::cout << "ObjectFactory()" << std::endl; }
  16. virtual ~ObjectFactory(){ std::cout << "~ObjectFactory()" << std::endl; }
  17. virtual ReflectObject* newInstance() = 0;
  18. };
  19. /************************************************************************/
  20. /***********反射器,用来管理(对象名,对象工厂)的映射关系******************/
  21. class Reflector
  22. {
  23. public:
  24. Reflector();
  25. ~Reflector();
  26. void registerFactory(const std::string& className, ObjectFactory *of);
  27. ReflectObject* getNewInstance(const std::string& className);
  28. private:
  29. std::map<std::string, ObjectFactory*> objectFactories;
  30. };
  31. /************************************************************************/
  32. /**********************获取反射器实例,全局唯一****************************/
  33. Reflector& reflector();
  34. /************************************************************************/
  35. /***********需要被反射的类,需要在其对应的 cpp 文件中进行反射声明***********/
  36. #define REFLECT(name)\
  37. class ObjectFactory_##name : public ObjectFactory{\
  38. public:\
  39. ObjectFactory_##name(){ std::cout << "ObjectFactory_" << #name << "()" << std::endl; }\
  40. virtual ~ObjectFactory_##name(){ std::cout << "~ObjectFactory_" << #name << "()" << std::endl; }\
  41. ReflectObject* newInstance() {\
  42. return new name(); \
  43. }\
  44. }; \
  45. class Register_##name{\
  46. public:\
  47. Register_##name(){\
  48. reflector().registerFactory(#name, new ObjectFactory_##name()); \
  49. }\
  50. };\
  51. Register_##name register_##name;
  52. /************************************************************************/
  53. /***********************根据类名获取对象实例******************************/
  54. template<typename T>
  55. T* getNewInstance(const std::string& className) {
  56. return dynamic_cast<T*>(reflector().getNewInstance(className));
  57. }
  58. // Reflector.cpp
  59. #include "Reflector.h"
  60. Reflector::Reflector()
  61. {
  62. }
  63. Reflector::~Reflector()
  64. {
  65. std::map<std::string, ObjectFactory*>::iterator it = objectFactories.begin();
  66. for (; it != objectFactories.end();++it)
  67. {
  68. delete it->second;
  69. }
  70. objectFactories.clear();
  71. }
  72. void Reflector::registerFactory(const std::string& className, ObjectFactory *of)
  73. {
  74. std::map<std::string, ObjectFactory*>::iterator it = objectFactories.find(className);
  75. if (it != objectFactories.end()) {
  76. std::cout << "该类已经存在……" << std::endl;
  77. }
  78. else {
  79. objectFactories[className] = of;
  80. }
  81. }
  82. ReflectObject* Reflector::getNewInstance(const std::string& className)
  83. {
  84. std::map<std::string, ObjectFactory*>::iterator it = objectFactories.find(className);
  85. if (it != objectFactories.end()) {
  86. ObjectFactory *of = it->second;
  87. return of->newInstance();
  88. }
  89. return NULL;
  90. }
  91. // 用来获取反射器对象,注意这是全局唯一的。
  92. Reflector& reflector() {
  93. static Reflector reflector;
  94. return reflector;
  95. }

抽象对象类的实现

  1. // Person.h
  2. #include "Reflector.h"
  3. // 让 Person 继承反射基类
  4. class Person : public ReflectObject
  5. {
  6. public:
  7. Person();
  8. virtual ~Person();
  9. virtual void show();
  10. };
  11. // Person.cpp
  12. Person::Person()
  13. {
  14. std::cout << "Person()" << std::endl;
  15. }
  16. Person::~Person()
  17. {
  18. std::cout << "~Person()" << std::endl;
  19. }
  20. void Person::show()
  21. {
  22. std::cout << "Hello, I'm person" << std::endl;
  23. }

具体对象类的实现

  1. #include "Person.h"
  2. class Allen : public Person
  3. {
  4. public:
  5. Allen()
  6. virtual ~Allen();
  7. virtual void show();
  8. };
  9. class Luffy : public Person
  10. {
  11. public:
  12. Luffy();
  13. virtual ~Luffy();
  14. virtual void show();
  15. };
  16. REFLECT(Allen);// 注册反射类,只能写在 cpp 文件中。
  17. Allen::Allen()
  18. {
  19. std::cout << "Allen()" << std::endl;
  20. }
  21. Allen::~Allen()
  22. {
  23. std::cout << "~Allen()" << std::endl;
  24. }
  25. void Allen::show()
  26. {
  27. std::cout << "Hello, I'm Allen" << std::endl;
  28. }
  29. REFLECT(Luffy); // 注册反射类,只能写在 cpp 文件中。
  30. Luffy::Luffy()
  31. {
  32. std::cout << "Luffy()" << std::endl;
  33. }
  34. Luffy::~Luffy()
  35. {
  36. std::cout << "~Luffy()" << std::endl;
  37. }
  38. void Luffy::show()
  39. {
  40. std::cout << "Hello, I'm Luffy" << std::endl;
  41. }

这是一个完整的反射的实现和测试实例,文章参考自
https://blog.csdn.net/q1007729991/article/details/56012253