• C++反射实现


    C++实现反射的一个简单实验,考虑并不充分。 

    typelist.h

    #ifndef _TYPELIST_H
    #define _TYPELIST_H
    class NullType {};
    
    //Typelist
    template <class T, class U>
    struct Typelist
    {
       typedef T Head;
       typedef U Tail;
    };
    template <class TList, class T> struct IndexOf;
            
    template <class T>
    struct IndexOf<NullType, T>
    {
       enum { value = -1 };
    };
            
    template <class T, class Tail>
    struct IndexOf<Typelist<T, Tail>, T>
    {
       enum { value = 0 };
    };
            
    template <class Head, class Tail, class T>
    struct IndexOf<Typelist<Head, Tail>, T>
    {
       private:
           enum { temp = IndexOf<Tail, T>::value };
       public:
           enum { value = (temp == -1 ? -1 : 1 + temp) };
    };
    #define LOKI_TYPELIST_1(T1) Typelist<T1, NullType>
    #define LOKI_TYPELIST_2(T1, T2) Typelist<T1, LOKI_TYPELIST_1(T2) >
    #define LOKI_TYPELIST_3(T1, T2, T3) Typelist<T1, LOKI_TYPELIST_2(T2, T3) >
    #define LOKI_TYPELIST_4(T1, T2, T3, T4) /
        Typelist<T1, LOKI_TYPELIST_3(T2, T3, T4) >
    #define LOKI_TYPELIST_5(T1, T2, T3, T4, T5) /
        Typelist<T1, LOKI_TYPELIST_4(T2, T3, T4, T5) >
    #define LOKI_TYPELIST_6(T1, T2, T3, T4, T5, T6) /
        Typelist<T1, LOKI_TYPELIST_5(T2, T3, T4, T5, T6) >
    #define LOKI_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) /
        Typelist<T1, LOKI_TYPELIST_6(T2, T3, T4, T5, T6, T7) >
    #define LOKI_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) /
        Typelist<T1, LOKI_TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
    #define LOKI_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) /
        Typelist<T1, LOKI_TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
    #define LOKI_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) /
        Typelist<T1, LOKI_TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
    #define LOKI_TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) /
        Typelist<T1, LOKI_TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
    #define LOKI_TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) /
        Typelist<T1, LOKI_TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, /
            T11, T12) >
    #define LOKI_TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,T13) /
        Typelist<T1, LOKI_TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, /
            T11, T12, T13) >
    #define LOKI_TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,T13,T14) /
        Typelist<T1, LOKI_TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, /
            T11, T12, T13,T14) >
    template<int v>
    struct Int2Type
    {
        enum {value = v};
    };
    #endif

    any.h

    #ifndef _ANY_H
    #define _ANY_H
    #include <vector>
    //#include "TypeList.h"
    //#include "Trait.h"
    //一个精简版的boost::any
    class any
    {
    public: // structors
       any(): content(0),counter(0)
       {
       }
       template<typename ValueType>
       any(const ValueType & value)
          : content(new holder<ValueType>(value)),counter(new int(1))
       {
       }
       any(const any & other)
       {
           if(other.counter && other.content)
           {
               content = other.content;
               counter = other.counter;
               ++(*counter);
           }
           else
           {
               content = 0;
               counter = 0;
           }
       }
           any & operator=(const any & rhs)
        {
            if(&rhs == this)
                return *this;
            else
            {      
                _destroy();
                if(rhs.counter && rhs.content)
                {
                    content = rhs.content;
                    counter = rhs.counter;
                    ++(*counter);
                }
                else
                {
                    content = 0;
                    counter = 0;
                }
                return *this;
            }
        }
       ~any()
       {
            _destroy();
       }
    private:
        void _destroy()
        {
            if(counter && content && --*counter <= 0)
            {
                delete counter;
                delete content;
            }
        }
    public: // queries
        bool empty() const
        {
           return !content;
        }
    public:
        class placeholder
        {
          public: // structors
            virtual ~placeholder()
            {
            }
         };
         template<typename ValueType>
         class holder : public placeholder
         {
           public: // structors
             holder(const ValueType & value)
               : held(value)
             {
             }
           public: // representation
              ValueType held;
          };
    public: // representation (public so any_cast can be non-friend)
       placeholder * content;
       int         * counter;
    };
    template<typename ValueType>
    inline ValueType any_cast(const any & operand)
    {
        any::holder<ValueType> * tmp = static_cast<any::holder<ValueType> *>(operand.content);
        return tmp->held;
    }
    #endif

    reflect.h

    #ifndef _REFLECT_H
    #define _REFLECT_H
    
    #include "any.h"
    #include <string>
    #include <map>
    
    
    
    
    class Value
    {
    public:
        Value(const any &value):_value(value){}
    
        Value(const Value &other):_value(other._value)
        {
            
        }
    
        Value & operator=(const Value & rhs)
        {
            if(&rhs == this)
                return *this;
            else
            {
                _value = rhs._value;
                return *this;
            }
        }
    
        const any& GetValue() const
        {
            return _value;
        }
    
        void SetValue(const any &value)
        {
            _value = value;
        }
    
    private:
        any _value;
    };
    
    class reflectBase;
    
    struct attribute_op
    {
        typedef Value (reflectBase::*func_get)();
        typedef void (reflectBase::*func_set)(const Value&);
    
        func_get _get;
        func_set _set;
    
    };
    
    
    class Attribute
    {
    
    public:    
    
        Attribute(){}
    
        Attribute(const std::string &name,attribute_op &op)
            :name(name),member_get(op._get),member_set(op._set)
        {}
        
    
        Value GetValue(reflectBase &object)
        {
            return (object.*member_get)();
    
        }
    
        void  SetValue(reflectBase &object,const Value &value)
        {
            (object.*member_set)(value);
        }
    
        const std::string &GetName()
        {
            return name;
        }
    
        ~Attribute()
        {
        }
    
    private:
        std::string name;
    
        attribute_op::func_get member_get;
        attribute_op::func_set member_set;
    };
    
    class param
    {
    public:
    
        param(){}
    
        param(const any& p1)
        {
            m_param.push_back(p1);
        }
    
        param(const any& p1,const any &p2)
        {
            m_param.push_back(p1);
            m_param.push_back(p2);
        }
    
    
        std::vector<Value> m_param;
    };
    
    
    struct memberFunc_op
    {
        typedef Value (reflectBase::*func)(const param &);
        func _call;
    };
    
    
    class reflectBase;
    
    class memberFunction
    {
    public:
    
        typedef memberFunc_op::func methord;
    
        memberFunction(const std::string &name,memberFunc_op &op)
            :funcname(name),_call(op._call)//,callret(op._call_ret)
        {}
    
        methord GetMethord()
        {
            return _call;
        }
        
        ~memberFunction()
        {
        }
    public:
        std::string funcname;
    
        memberFunc_op::func _call;
    };
    
    class classdef;
    
    class reflectBase
    {
    public:
        virtual classdef    *GetClassDef() = 0;
        virtual ~reflectBase(){};
    };
    
    
    class classdef
    {
    public:
    
        typedef reflectBase* (*creator)();
    
        classdef(const std::string& name,classdef::creator _creator):classname(name),instance_creator(_creator){} 
    
        reflectBase *CreateInstance()
        {
            return instance_creator();
        }
        
        void AddAttribute(const std::string &name,Attribute *attr)
        {
            attributes.insert(std::make_pair(name,attr));
        }
    
        void AddMemberFunc(const std::string &name,memberFunction *func)
        {
            memberfuncs.insert(std::make_pair(name,func));
        }
    
        memberFunction *GetMemFunc(const std::string &name)
        {
            std::map<std::string,memberFunction*>::iterator it = memberfuncs.find(name);
            if(it != memberfuncs.end())
                return it->second;
            return NULL;
        }
    
        Attribute* FindAttribute(const std::string &name)
        {
            std::map<std::string,Attribute*>::iterator it = attributes.find(name);
            if(it != attributes.end())
                return it->second;
            return NULL;
        }
    
    
    public:
        std::string classname;
        std::map<std::string,Attribute*> attributes;
        std::map<std::string,memberFunction*> memberfuncs;
        creator instance_creator;
    };
    
    
    #define DECLARE_REFLECT_CLASS(NAME,CLASSNAME)/
        static reflectBase *CreateInstance()/
        {/
            return new NAME;/
        }/
        static classdef *class_def##NAME;/
        classdef *GetClassDef()/
        {/
            return class_def##NAME;/
        }/
        struct regClass##NAME/
        {/
            regClass##NAME(){/
            NAME::class_def##NAME = new classdef(CLASSNAME,static_cast<classdef::creator>(&NAME::CreateInstance));/
            }/
        };/
        static regClass##NAME _regClass##NAME;
    
    #define IMPLEMENT_REFLECT_CLASS(NAME)/
        classdef *NAME::class_def##NAME;/
        NAME::regClass##NAME _regClass##NAME;
    
    
    #define REGISTER_MEMBER(CLASS,NAME,TYPE,MEMBERNAME)/
        Value Get##NAME()/
        {/
            return Value(NAME);/
        }/
        void Set##NAME(const Value &value)/
        {/
            NAME = any_cast<TYPE>(value.GetValue());/
        }/
        struct reg##NAME{/
            reg##NAME()/
            {/
                attribute_op op;/
                op._get = static_cast<attribute_op::func_get>(&CLASS::Get##NAME);/
                op._set = static_cast<attribute_op::func_set>(&CLASS::Set##NAME);/
                Attribute *attr = new Attribute(MEMBERNAME,op);/
                CLASS::class_def##CLASS->AddAttribute(MEMBERNAME,attr);/
            }/
        };/
        static reg##NAME  _reg##NAME;
    
    #define IMPLEMENT_MEMBER(CLASSNAME,NAME)/
        CLASSNAME::reg##NAME CLASSNAME::_reg##NAME;
    
    
    #define REGISTER_MEMBERFUNCTION_0(CLASS,NAME,RET,FUNCNAME)/
        template<typename Ret>/
        class doCall##NAME/
        {/
        public:/
            static Value doCall(CLASS *obj,const param &_param)/
            {/
                typedef LOKI_TYPELIST_1(void) voidType;/
                return call(obj,_param,Int2Type<IndexOf<voidType,Ret>::value == 0>());/
            }/
        private:/
            static Value call(CLASS *obj,const param &_param,Int2Type<true>)/
            {/
                obj->NAME();/
                return Value(any());/
            }/
            static Value call(CLASS *obj,const param &_param,Int2Type<false>)/
            {/
                return Value(obj->NAME());/
            }/
        };/
        Value call_##NAME(const param &_param = param())/
        {/
            return doCall##NAME<RET>::doCall(this,_param);/
        }/
        struct regMemberFunc0##NAME/
        {/
            regMemberFunc0##NAME()/
            {/
                memberFunc_op op;/
                op._call = static_cast<memberFunc_op::func>(&CLASS::call_##NAME);/
                memberFunction *memfunc = new memberFunction(FUNCNAME,op);/
                CLASS::class_def##CLASS->AddMemberFunc(FUNCNAME,memfunc);/
            }/
        };/
        static regMemberFunc0##NAME _regMemberFunc0##NAME;
    
    #define IMPLEMENT_MEMBERFUNCTION0(CLASSNAME,NAME)/
        CLASSNAME::regMemberFunc0##NAME CLASSNAME::_regMemberFunc0##NAME;
    
    #define REGISTER_MEMBERFUNCTION_1(CLASS,NAME,RET,PARAM1,FUNCNAME)/
        template<typename Ret>/
        class doCall##NAME/
        {/
        public:/
            static Value doCall(CLASS *obj,const param &_param)/
            {/
                typedef LOKI_TYPELIST_1(void) voidType;/
                return call(obj,_param,Int2Type<IndexOf<voidType,Ret>::value == 0>());/
            }/
        private:/
            static Value call(CLASS *obj,const param &_param,Int2Type<true>)/
            {/
                obj->NAME(any_cast<PARAM1>(_param.m_param[0].GetValue()));/
                return Value(any());/
            }/
            static Value call(CLASS *obj,const param &_param,Int2Type<false>)/
            {/
                return Value(obj->NAME(any_cast<PARAM1>(_param.m_param[0].GetValue())));/
            }/
        };/
        Value call_##NAME(const param &_param = param())/
        {/
            return doCall##NAME<RET>::doCall(this,_param);/
        }/
        struct regMemberFunc1##NAME/
        {/
            regMemberFunc1##NAME()/
            {/
                memberFunc_op op;/
                op._call = static_cast<memberFunc_op::func>(&CLASS::call_##NAME);/
                memberFunction *memfunc = new memberFunction(FUNCNAME,op);/
                CLASS::class_def##CLASS->AddMemberFunc(FUNCNAME,memfunc);/
            }/
        };/
        static regMemberFunc1##NAME _regMemberFunc1##NAME;
    
    #define IMPLEMENT_MEMBERFUNCTION1(CLASSNAME,NAME)/
        CLASSNAME::regMemberFunc1##NAME CLASSNAME::_regMemberFunc1##NAME;
    
    #define REGISTER_MEMBERFUNCTION_2(CLASS,NAME,RET,PARAM1,PARAM2,FUNCNAME)/
        template<typename Ret>/
        class doCall##NAME/
        {/
        public:/
            static Value doCall(CLASS *obj,const param &_param)/
            {/
                typedef LOKI_TYPELIST_1(void) voidType;/
                return call(obj,_param,Int2Type<IndexOf<voidType,Ret>::value == 0>());/
            }/
        private:/
            static Value call(CLASS *obj,const param &_param,Int2Type<true>)/
            {/
                obj->NAME(any_cast<PARAM1>(_param.m_param[0].GetValue()),any_cast<PARAM2>(_param.m_param[1].GetValue()));/
                return Value(any());/
            }/
            static Value call(CLASS *obj,const param &_param,Int2Type<false>)/
            {/
                return Value(obj->NAME(any_cast<PARAM1>(_param.m_param[0].GetValue()),any_cast<PARAM2>(_param.m_param[1].GetValue())));/
            }/
        };/
        Value call_##NAME(const param &_param = param())/
        {/
            return doCall##NAME<RET>::doCall(this,_param);/
        }/
        struct regMemberFunc2##NAME/
        {/
            regMemberFunc2##NAME()/
            {/
                memberFunc_op op;/
                op._call = static_cast<memberFunc_op::func>(&CLASS::call_##NAME);/
                memberFunction *memfunc = new memberFunction(FUNCNAME,op);/
                CLASS::class_def##CLASS->AddMemberFunc(FUNCNAME,memfunc);/
            }/
        };/
        static regMemberFunc2##NAME _regMemberFunc2##NAME;
    
    #define IMPLEMENT_MEMBERFUNCTION2(CLASSNAME,NAME)/
        CLASSNAME::regMemberFunc2##NAME CLASSNAME::_regMemberFunc2##NAME;
        
    #endif

    测试代码

    // reflectionTest.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "any.h"
    #include "reflect.h"
    
    class test : public reflectBase
    {
    public:
    
        test(){}
    
        void print(int a)
        {
            printf("haha %d/n",a);
        }
    
        void print_void()
        {
            printf("print_void/n");
        }
    
        void print2(const std::string &a,const std::string &b)
        {
            printf("%s,%s/n",a.c_str(),b.c_str());
        }
    
        int add(int other)
        {
            return membera + other;
        }
    
        DECLARE_REFLECT_CLASS(test,"test")
        REGISTER_MEMBER(test,membera,int,"membera")
        REGISTER_MEMBER(test,memberb,double,"memberb")
        REGISTER_MEMBERFUNCTION_0(test,print_void,void,"print_void")
        REGISTER_MEMBERFUNCTION_1(test,print,void,int,"print")
        REGISTER_MEMBERFUNCTION_2(test,print2,void,std::string,std::string,"print2")
        REGISTER_MEMBERFUNCTION_1(test,add,int,int,"add")
    
        int membera;
        double memberb;
    };
    
    IMPLEMENT_REFLECT_CLASS(test)
    IMPLEMENT_MEMBER(test,membera)
    IMPLEMENT_MEMBER(test,memberb)
    IMPLEMENT_MEMBERFUNCTION1(test,print)
    IMPLEMENT_MEMBERFUNCTION0(test,print_void)
    IMPLEMENT_MEMBERFUNCTION2(test,print2)
    IMPLEMENT_MEMBERFUNCTION1(test,add)
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        test t;
        t.membera = 10;
        t.memberb = 12.0;
    
        reflectBase *rb = &t;
    
        Attribute *attr = rb->GetClassDef()->FindAttribute("membera");
        attr->SetValue(*rb,any(100));
        printf("%d/n",any_cast<int>(attr->GetValue(*rb).GetValue()));
    
        memberFunction *memfun = rb->GetClassDef()->GetMemFunc("print");
        memberFunction::methord methord = memfun->GetMethord();
    
        (rb->*methord)(param(100));
        
    
    
        memfun = rb->GetClassDef()->GetMemFunc("print_void");
        
        methord = memfun->GetMethord();
    
        (rb->*methord)(param());
    
        memfun = rb->GetClassDef()->GetMemFunc("print2");
        methord = memfun->GetMethord();
        (rb->*methord)(param(std::string("hello"),std::string("kenny")));
    
        reflectBase *rb1 = rb->GetClassDef()->CreateInstance();
    
        printf("%s/n",rb1->GetClassDef()->classname.c_str());
    
        attr = rb1->GetClassDef()->FindAttribute("membera");
        attr->SetValue(*rb1,any(1000));
        printf("%d/n",any_cast<int>(attr->GetValue(*rb1).GetValue()));
    
        memfun = rb->GetClassDef()->GetMemFunc("add");
    
        methord = memfun->GetMethord();
    
        int sum = any_cast<int>((rb->*methord)(param(100)).GetValue());
    
    
        test *t1 = (test*)rb1; 
    
        getchar();
    
        return 0;
    }
  • 相关阅读:
    opencv-0-项目启程
    [SketchUp]-绘制自己的家
    C51_PID 水温控制系统
    latex-列表环境
    nCOV 数据简要分析 (0326)
    引入OpenCV导致私有内存巨大
    【带着canvas去流浪(15)】threejs fundamentals翻译系列1-scene graph
    【一统江湖的大前端(9)】TensorFlow.js 开箱即用的深度学习工具
    【一统江湖的大前端(8)】matter.js 经典物理
    2019年12月前端面经及总结(西安,杭州)
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2607300.html
Copyright © 2020-2023  润新知