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; }