c++利用属性名设置和获取属性值
/*
* @Filename:CMetaDataManager.h
* @Date:2016-10-21
* @Author:yuanzuochao
* @Description:
*
* @History:
* Date Author Records
* 2016-10-21 yuanzuochao Create
*/
#ifndef CMETADATAMANAGER_H
#define CMETADATAMANAGER_H
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <typeinfo>
#include <map>
struct IInfo
{
virtual std::string getType() const = 0;
virtual std::string getName() const = 0;
virtual ~IInfo(){}
};
template<class _Class, class _Type> class CField;
template<class _Class, class _Type>
struct ISetter
{
virtual void accecpt(CField<_Class, _Type>* field, _Class* ins, _Type value) = 0;
virtual ~ISetter(){}
};
template<class _Class, class _Type>
struct IGetter
{
virtual _Type accecpt(const CField<_Class, _Type>* field, _Class* ins) const = 0;
virtual ~IGetter(){}
};
template<class _Class, class _Type>
class const_ref_param_setter:public ISetter<_Class, _Type>
{
public:
typedef void (_Class::*Setter) (const _Type&);
public:
const_ref_param_setter(Setter setter):
m_pSetter(setter)
{
}
void set(_Class* ins, _Type value)
{
(ins->*m_pSetter)(value);
}
void accecpt(CField<_Class, _Type>* field, _Class* ins, _Type value)
{
field->set(this, ins, value);
}
private:
Setter m_pSetter;
};
template<class _Class, class _Type>
class ordinary_setter:public ISetter<_Class, _Type>
{
public:
typedef void (_Class::*Setter) (_Type);
public:
ordinary_setter(Setter setter):
m_pSetter(setter)
{
}
void set(_Class* ins, _Type value)
{
(ins->*m_pSetter)(value);
}
void accecpt(CField<_Class, _Type>* field, _Class* ins, _Type value)
{
field->set(this, ins, value);
}
private:
Setter m_pSetter;
};
template<class _Class, class _Type>
class const_ref_ret_getter:public IGetter<_Class, _Type>
{
public:
typedef const _Type& (_Class::*Getter) () const;
public:
const_ref_ret_getter(Getter getter):
m_pGetter(getter)
{
}
const _Type& get(_Class* ins) const
{
return (ins->*m_pGetter)();
}
_Type accecpt(const CField<_Class, _Type>* field, _Class* ins) const
{
return field->get(this, ins);
}
private:
Getter m_pGetter;
};
template<class _Class, class _Type>
class ordinary_getter:public IGetter<_Class, _Type>
{
public:
typedef _Type (_Class::*Getter) () const;
public:
ordinary_getter(Getter getter):
m_pGetter(getter)
{
}
_Type get(_Class* ins) const
{
return (ins->*m_pGetter)();
}
_Type accecpt(const CField<_Class, _Type>* field, _Class* ins) const
{
return field->get(this, ins);
}
private:
Getter m_pGetter;
};
template<class _Class, class _Type>
class CField:public IInfo
{
public:
typedef _Type _Class::* FieldType;
typedef typename const_ref_param_setter<_Class, _Type>::Setter type_const_ref_param_setter;
typedef typename ordinary_setter<_Class, _Type>::Setter type_ordinary_setter;
typedef typename const_ref_ret_getter<_Class, _Type>::Getter type_const_ref_ret_getter;
typedef typename ordinary_getter<_Class, _Type>::Getter type_ordinary_getter;
public:
CField(std::string name, type_const_ref_param_setter setter, type_const_ref_ret_getter getter):
m_pField(NULL),
m_strName(name)
{
m_pSetter = new const_ref_param_setter<_Class,_Type>(setter);
m_pGetter = new const_ref_ret_getter<_Class, _Type>(getter);
}
CField(std::string name, type_ordinary_setter setter, type_ordinary_getter getter):
m_pField(NULL),
m_strName(name)
{
m_pSetter = new ordinary_setter<_Class,_Type>(setter);
m_pGetter = new ordinary_getter<_Class, _Type>(getter);
}
CField(std::string name, FieldType field):
m_pField(field),
m_strName(name),
m_pSetter(NULL),
m_pGetter(NULL)
{
}
~CField()
{
if(m_pGetter)
{
delete m_pGetter;
m_pGetter = NULL;
}
if(m_pSetter)
{
delete m_pSetter;
m_pSetter = NULL;
}
}
std::string getType() const
{
return typeid(_Type).name();
}
std::string getName() const
{
return m_strName;
}
void set(_Class* ins, _Type value)
{
if(m_pField)
{
ins->*m_pField = value;
}else if(m_pSetter)
{
m_pSetter->accecpt(this, ins, value);
}else
{
std::cout<<"no setter matched!"<<std::endl;
}
}
_Type get(_Class* ins) const
{
_Type value;
if(m_pField)
{
value = ins->*m_pField;
}else if(m_pGetter)
{
value = m_pGetter->accecpt(this, ins);
}else
{
std::cout<<"no getter matched!"<<std::endl;
}
return value;
}
void set(const_ref_param_setter<_Class, _Type>* setter, _Class* ins, _Type value)
{
setter->set(ins, value);
}
_Type get(const const_ref_ret_getter<_Class, _Type>* getter, _Class* ins) const
{
return getter->get(ins);
}
void set(ordinary_setter<_Class, _Type>* setter, _Class* ins, _Type value)
{
setter->set(ins, value);
}
_Type get(const ordinary_getter<_Class, _Type>* getter, _Class* ins) const
{
return getter->get(ins);
}
private:
FieldType m_pField;
std::string m_strName;
ISetter<_Class, _Type>* m_pSetter;
IGetter<_Class, _Type>* m_pGetter;
};
template <class _Class>
class CClass:public IInfo
{
typedef std::map<std::string, IInfo*>::value_type type_map;
typedef std::map<std::string, IInfo*>::iterator type_iter;
typedef std::map<std::string, IInfo*>::const_iterator type_const_iter;
public:
~CClass()
{
type_iter iter = m_mapFieldInfo.begin();
for(; iter != m_mapFieldInfo.end(); ++iter)
{
delete (iter->second);
}
m_mapFieldInfo.clear();
}
std::string getType() const
{
return typeid(_Class).name();
}
std::string getName() const
{
return typeid(_Class).name();
}
public:
//typedef typename CField<_Class, _Type>::type_const_ref_param_setter type_const_ref_param_setter;
//typedef typename CField<_Class, _Type>::type_const_ref_ret_getter type_const_ref_ret_getter;
template<class _Type>
void addField(std::string name, void (_Class::*setter)(const _Type&), const _Type& (_Class::*getter)() const )
{
IInfo* pField = new CField<_Class, _Type>(name, setter, getter);
m_mapFieldInfo.insert(type_map(name, pField));
}
template<class _Type>
void addField(std::string name, void (_Class::*setter)(_Type), _Type (_Class::*getter)() const)
{
IInfo* pField = new CField<_Class, _Type>(name, setter, getter);
m_mapFieldInfo.insert(type_map(name, pField));
}
template<class _Type>
void addField(std::string name, _Type (_Class::*director))
{
IInfo* pField = new CField<_Class, _Type>(name, director);
m_mapFieldInfo.insert(type_map(name, pField));
}
template<class _Type>
void set(std::string name, _Class* ins, _Type value) const
{
type_const_iter iter = m_mapFieldInfo.find(name);
if(iter == m_mapFieldInfo.end())
{
return;
}
CField<_Class, _Type>* pField = dynamic_cast<CField<_Class, _Type>*>(iter->second);
if(NULL == pField)
{
return;
}
pField->set(ins, value);
}
template<class _Type>
_Type get(std::string name, _Class* ins) const
{
_Type value;
type_const_iter iter = m_mapFieldInfo.find(name);
do
{
if(iter == m_mapFieldInfo.end())
{
std::cout<<"name: "<<name<<" not be found"<<std::endl;
break;
}
CField<_Class, _Type>* pField = dynamic_cast<CField<_Class, _Type>*>(iter->second);
if(NULL == pField)
{
std::cout<<"dynamic_cast failed"<<std::endl;
break;
}
value = pField->get(ins);
}while(0);
return value;
}
std::string getFieldType(std::string name) const
{
std::string type;
type_const_iter iter = m_mapFieldInfo.find(name);
if(iter == m_mapFieldInfo.end())
{
std::cout<<"name: "<<name<<" not be found"<<std::endl;
return type;
}
type = (iter->second)->getType();
return type;
}
private:
std::map<std::string, IInfo*> m_mapFieldInfo;
};
class CMetaDataManager
{
typedef std::map<std::string, IInfo*>::value_type type_map;
typedef std::map<std::string, IInfo*>::iterator type_iter;
typedef std::map<std::string, IInfo*>::const_iterator type_const_iter;
public:
template<class _Class>
void registry()
{
IInfo* pClass = new CClass<_Class>();
m_mapClassInfo.insert(type_map(typeid(_Class).name(), pClass));
}
template<class _Class, class _Type>
void addField(std::string name, void (_Class::*setter)(const _Type&), const _Type& (_Class::*getter)() const )
{
type_iter iter = m_mapClassInfo.find(typeid(_Class).name());
if(iter == m_mapClassInfo.end())
{
return;
}
CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);
if(NULL == pClass)
{
return;
}
pClass->addField(name, setter, getter);
}
template<class _Class, class _Type>
void addField(std::string name, void (_Class::*setter)(_Type), _Type (_Class::*getter)() const)
{
type_iter iter = m_mapClassInfo.find(typeid(_Class).name());
if(iter == m_mapClassInfo.end())
{
return;
}
CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);
if(NULL == pClass)
{
return;
}
pClass->addField(name, setter, getter);
}
template<class _Class, class _Type>
void addField(std::string name, _Type (_Class::*director))
{
type_iter iter = m_mapClassInfo.find(typeid(_Class).name());
if(iter == m_mapClassInfo.end())
{
return;
}
CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);
if(NULL == pClass)
{
return;
}
pClass->addField(name, director);
}
template<class _Class, class _Type>
void set(std::string name, _Class* ins, _Type value) const
{
type_const_iter iter = m_mapClassInfo.find(typeid(_Class).name());
if(iter == m_mapClassInfo.end())
{
return;
}
CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);
if(NULL == pClass)
{
return;
}
pClass->set(name, ins, value);
}
template<class _Class, class _Type>
_Type get(std::string name, _Class* ins) const
{
_Type value;
type_const_iter iter = m_mapClassInfo.find(typeid(_Class).name());
do
{
if(iter == m_mapClassInfo.end())
{
break;
}
CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);
if(NULL == pClass)
{
break;
}
value = pClass->get<_Type>(name, ins);
}while(0);
return value ;
}
template<class _Class>
std::string getFieldType(std::string name) const
{
std::string type="";
type_const_iter iter = m_mapClassInfo.find(typeid(_Class).name());
if(iter == m_mapClassInfo.end())
{
return type;
}
CClass<_Class>* pClass = dynamic_cast<CClass<_Class>*>(iter->second);
if(NULL == pClass)
{
return type;
}
return pClass->getFieldType(name);
}
private:
std::map<std::string, IInfo*> m_mapClassInfo;
};
#endif //CMETADATAMANAGER_H