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;
}
原文链接: https://www.cnblogs.com/sniperHW/archive/2010/11/24/2607300.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17813
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!