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;
}
posted @ 2010-11-24 15:11  sniperHW  阅读(957)  评论(0编辑  收藏  举报