欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++利用属性名设置和获取属性值

程序员文章站 2022-05-28 17:33:34
...

/*

 * @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