C++的反射机制

阅读更多

 

 

用过java的,都会很喜欢java的反射机制,非常的方便啊,通过配置修改调用类。

c++通过自己的包装也可以实现类似的功能,就是麻烦了点。

C++的反射分为两个部分,一个是类反射,另一个是函数反射。实际上类反射也是函数反射的一种,可以理解为是构造函数的反射。

1、类反射:

    原文:https://blog.csdn.net/ihc523/article/details/24143655

   

#ifndef __BASE_H__
#define __BASE_H__
#include 
#include 
#include 

// 使用模板,每个基类单独生成一个 ClassRegister
// 好处是需要反射的类不需要去继承 Object 对象
// ClassRegister 用来管理类名->类构造函数的映射,对外提供根据类名构造对象对函数
template
class ClassRegister {
  public:
    typedef ClassName* (*Constructor)(void);
  private:
    typedef std::map ClassMap;
    ClassMap constructor_map_;
  public:
    // 添加新类的构造函数
    void AddConstructor(const std::string class_name, Constructor constructor) {
      typename ClassMap::iterator it = constructor_map_.find(class_name);
      if (it != constructor_map_.end()) {
        std::cout << "error!";
        return;
      }
      constructor_map_[class_name] = constructor;
    }
    // 根据类名构造对象
    ClassName* CreateObject(const std::string class_name) const {
      typename ClassMap::const_iterator it = constructor_map_.find(class_name);
      if (it == constructor_map_.end()) {
        return nullptr;
      }
      return (*(it->second))();
    }
};

// 用来保存每个基类的 ClassRegister static 对象,用于全局调用
template 
ClassRegister& GetRegister() {
  static ClassRegister class_register;
  return class_register;
}

// 每个类的构造函数,返回对应的base指针
template 
BaseClassName* NewObject() {
  return new SubClassName();
}

// 为每个类反射提供一个 helper,构造时就完成反射函数对注册
template
class ClassRegisterHelper {
  public:
  ClassRegisterHelper(
      const std::string sub_class_name,
      typename ClassRegister::Constructor constructor) {
    GetRegister().AddConstructor(sub_class_name, constructor);
  }
  ~ClassRegisterHelper(){}
};

// 提供反射类的注册宏,使用时仅提供基类类名和派生类类名
#define RegisterClass(base_class_name, sub_class_name) \
  static ClassRegisterHelper \
      sub_class_name##_register_helper( \
          #sub_class_name, NewObject);

// 创建对象的宏
#define CreateObject(base_class_name, sub_class_name_as_string) \
  GetRegister().CreateObject(sub_class_name_as_string)

#endif

 

 

 使用示例:

#include 
#include 
#include 
#include "base3.h"
using namespace std;

class base
{
  public:
    base() {}
    virtual void test() { std::cout << "I'm base!" << std::endl; }
    virtual ~base() {}
};

class A : public base
{
  public:
    A() { cout << " A constructor!" << endl; }
    virtual void test() { std::cout << "I'm A!" <test();
  delete p1;
  p1 = CreateObject(base, "B");
  p1->test();
  delete p1;
  base2* p2 = CreateObject(base2, "C");
  p2->test();
  delete p2;
  return 0;
}

 2、函数反射:

//定义反射工厂类以及基类NSObject
#ifndef __NS_OBJECT_FACTORYE_H__
#define __NS_OBJECT_FACTORYE_H__
 
#include 
#include 
 
 
typedef void* (*SEL)(void);
typedef SEL (*callFuc)(void);
 
class NSObject{
public:
    Base(){};
    ~Base(){};
};
 
struct NSObjectFactory {
 
    typedef std::map map_type;
    typedef std::map fuc_map_type;
 
private:
 
    static map_type * m_map;
    static fuc_map_type * fuc_map;
 
protected:
 
public:
 
    static NSObject * createInstance(std::string const& s){
        map_type::iterator it = getMap()->find(s);
        if(it == getMap()->end())
            return 0;
        return it->second();
    }
  
    static SEL callFaction(std::string const& s) {
        fuc_map_type::iterator it = getFunctionMap()->find(s);
        if(it == getFunctionMap()->end())
            return 0;
        return it->second();
  
    }
 
    static map_type * getMap(){
        // never delete'ed. (exist until program termination)
        // because we can't guarantee correct destruction order 
        if(!m_map) { m_map = new map_type; } 
        return m_map;
    }
 
    static fuc_map_type* getFunctionMap() {
  
        if(!fuc_map) { fuc_map = new fuc_map_type(); } 
  
        return fuc_map; 
  
    }
     
};
 
NSObjectFactory::map_type * NSObjectFactory::m_map = 0;
 
NSObjectFactory::fuc_map_type * NSObjectFactory::fuc_map = 0;
 
template NSObject * createT() { return (NSObject *)(new T); }
 
 
template
struct NSObjectRegister : NSObjectFactory { 
    NSObjectRegister(std::string const& s) { 
        getMap()->insert(std::make_pair(s, &createT));
    }
};
 
#define REFECTION_CLASS_IMPLEMENT_DEFINE(NAME) \
    virtual string toString(){return #NAME;}; \
    static NSObjectRegister registerNSObject
 
#define REFECTION_CLASS_IMPLEMENT(NAME) \
    NSObjectRegister NAME::registerNSObject(#NAME)
 
#define NSClassFromString(NAME) \
    NSObjectFactory::createInstance(NAME)
 
struct FuctionRegister : NSObjectFactory { 
    FuctionRegister(std::string const& s, callFuc f) { 
        getFunctionMap()->insert(std::make_pair(s, f));
    }
  
};
  
#define REFECTION_FUNCTION_IMPLEMENT(NAME) \
    static FuctionRegister* f_reg_##NAME = new FuctionRegister(#NAME, (callFuc)NAME)
 
#define NSSelectorFromString(NAME) \
    NSObjectFactory::callFaction(NAME)
 
#endif // __NS_OBJECT_FACTORYE_H__

 

//示例封装成员函数反射方法定义一个base类
#define __EJ_GET_POINTER_TO(NAME) \
    SEL _ptr_to_##NAME() { \
        return (SEL)NAME; \
    } \
    REFECTION_FUNCTION_IMPLEMENT(_ptr_to_##NAME);
 
#define EJ_BIND_FUNCTION_DEFINE(NAME, ARGC_NAME, ARGV_NAME) \
    int _func_##NAME(size_t ARGC_NAME, const char* ARGV_NAME)
 
#define EJ_BIND_FUNCTION(CLASS, NAME, ARGC_NAME, ARGV_NAME) \
    \
    static int _##CLASS##_func_##NAME( \
        Base* object, \
        size_t argc, \
        const char argv[] \
    ) { \
        CLASS* instance = (CLASS*)object; \
        int ret = instance->_func_##NAME(argc, argv); \
        return ret; \
    } \
    __EJ_GET_POINTER_TO(_##CLASS##_func_##NAME)\
    \
    /* The actual implementation for this method */ \
    int CLASS::_func_##NAME(size_t ARGC_NAME, const char* ARGV_NAME)
 
class Base: public NSObject {
public:
    Base();
    ~Base();
    REFECTION_CLASS_IMPLEMENT_DEFINE(Base);//反射类申明
 
    EJ_BIND_FUNCTION(EJBindingEjectaCore,include, argc, argv )//反射成员函数申明
};
 
REFECTION_CLASS_IMPLEMENT(Base);//反射类实现
 
//反射成员函数类申明
EJ_BIND_FUNCTION(EJBindingEjectaCore,include, argc, argv ) {
    if( argc < 1 ) { return -1; }
    return 1;
}

 

使用示例:

//使用方法
typedef int (*CALL_BACK)( Base* object,  size_t argc,  const char argv[] );
 
int main(){
  
    NSObject* object = NSClassFromString("Base");//获得反射对象
    SEL callback = NSSelectorFromString("_ptr_to__Base_func_include");//获得函数指针
    ((CALL_BACK)callback)((Base*)object, 0, NULL);//调用静态函数使其调用object对象的成员函数
    return 0;
  
}

 

你可能感兴趣的:(C++的反射机制)