加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C中的一种反思

发布时间:2020-12-16 07:01:58 所属栏目:百科 来源:网络整理
导读:我试图在C中实现有限的反射,这样我就可以在存储的对象上调用getter和setter.这是我到目前为止所做的 主要代码 #ifndef REFLECTION_MANAGER_HPP_#define REFLECTION_MANAGER_HPP_#include iostream#include stringtemplate class Owner,class IOType class Si
我试图在C中实现有限的反射,这样我就可以在存储的对象上调用getter和setter.这是我到目前为止所做的

主要代码

#ifndef REFLECTION_MANAGER_HPP_
#define REFLECTION_MANAGER_HPP_

#include <iostream>
#include <string>


template <class Owner,class IOType> 
class SingleProperty {
public:
  typedef IOType    (Owner::*get_func_t)(); 
  typedef void    (Owner::*set_func_t)( IOType Value );

  inline SingleProperty(get_func_t Getter,set_func_t Setter ): m_Getter(Getter),m_Setter(Setter) {
  }
  get_func_t        m_Getter;
  set_func_t        m_Setter;
};

class ReflectionManager {
public:
  static ReflectionManager& Instance() {
    static ReflectionManager instance;
    return instance;
  }

  template <class Owner,class IOType> 
  void RegisterProperty(  std::string class_name,std::string property_name,typename SingleProperty<Owner,IOType>::get_func_t GetFn,IOType>::set_func_t SetFn)  {
    SingleProperty<Owner,IOType>* pProperty = new SingleProperty<Owner,IOType>(GetFn,SetFn );
    m_class_memeber_map[class_name][property_name] = pProperty;
  }

  template <class Owner> void put(std::string key,void *value,std::string class_name = NULL ) {
    Owner *ptr = reinterpret_cast<Owner*>(value);
    std::map<std::string,std::map< std::string,void*> >::iterator pos = m_class_memeber_map.find(class_name);
    if ( pos == m_class_memeber_map.end()) {
      return; // handle the error
    }
    for ( std::map< std::string,void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr ) {
      SingleProperty<Owner,std::string> *ptr = (SingleProperty<Owner,std::string> *)itr->second;
      (ptr->*m_Getter)();
    }
  }
private:
  ReflectionManager() {
  }
  ReflectionManager(ReflectionManager const&); 
  void operator=(ReflectionManager const&);

  std::map<std::string,void*> > m_class_memeber_map;

};

#endif

致电代码

这将被称为如下

ReflectionManager::Instance().RegisterProperty<Person,std::string>("Person","m_name",&Person::GetName,&Person::SetName);
  ReflectionManager::Instance().RegisterProperty<Person,"m_dept",&Person::GetDept,&Person::SetDept);
  ReflectionManager::Instance().RegisterProperty<Person,int>("Person","m_age",&Person::GetAge,&Person::SetAge);

  Person p1;
  p1.SetName("Avinash");
  p1.SetDept("Gemfire Native Client");
  p1.SetAge(34);

  ReflectionManager::Instance().put<Person>( "key1",&p1,"Person");

我已经在地图中存储了getter和setter,但是在put函数中我无法调用它,因为我不知道类型.

问题

基本上我如何实现for循环for(std :: map< std :: string,void *> :: iterator itr = pos-> second.begin(); itr!= pos-> second.end (); itr)我想迭代每个元素并调用相应的getter和setter方法.

我尝试了这个但是没有用.

(ptr->*((itr->second).m_Getter))();

我找到的另一种方法会赞赏评论

template <class Owner,IOType>::set_func_t SetFn)  {

      SingleProperty<Owner,SetFn );
      m_class_memeber_map[class_name][property_name] = pProperty;
      m_property_type_map[class_name].push_back(std::make_pair(property_name,TypeName<IOType>::get()));

  }

  template <class Owner> void put(std::string key,std::string class_name = NULL ) {
    Owner *pOwner  = reinterpret_cast<Owner*>(value);
    std::map<std::string,void*> >::iterator pos = m_class_memeber_map.find(class_name);

    std::vector<std::pair<std::string,std::string> > vector_property_map = m_property_type_map.find(class_name)->second;
    for ( std::vector<std::pair<std::string,std::string> >::iterator itr = vector_property_map.begin();itr != vector_property_map.end(); ++itr ) {
        std::map< std::string,void*>::iterator pos_getter_setter_fn = pos->second.find(itr->first);
        if ( itr->second == "int" ) {
          SingleProperty<Owner,int> *ptr = (SingleProperty<Owner,int> *)pos_getter_setter_fn->second;
          (pOwner->*(ptr->m_Getter))();
        } else if ( itr->second == "string" ) {
          SingleProperty<Owner,std::string> *)pos_getter_setter_fn->second;
          (pOwner->*(ptr->m_Getter))();
        } 
    }
  }

解决方法

这些指针是指向所有者类型的函数成员的指针:

get_func_t m_Getter;
set_func_t m_Setter;

你为什么试着给他们打电话给SingleProperty<>指针作为对象?

Owner *ptr = reinterpret_cast<Owner*>(value);
for ( std::map< std::string,void*>::iterator itr = pos->second.begin();
   itr != pos->second.end(); ++itr )
{
  SingleProperty<Owner,std::string> *ptr = 
      (SingleProperty<Owner,std::string> *)itr->second;
  // Here is the flaw,you are trying to call m_Getter from SingleProperty object
  // pointer,but it must be Owner pointer!
  (ptr->*m_Getter)();
}

此外,您必须正确传递属性类型作为模板参数IOType.
我不确定你试图用这个函数做什么以及用废弃的返回类型调用getter的效果是什么,但是从抽象语法的角度看它应该是这样的:

template <class Owner,class IOType> void put(const std::string& key,Owner* value,const std::string& class_name = "")
{
    std::map<std::string,std::map<std::string,void*> >::iterator pos =
        m_class_memeber_map.find(class_name);

    if(pos == m_class_memeber_map.end())
    {
       return; // handle the error
    }

    for(std::map<std::string,void*>::iterator itr = pos->second.begin();
       itr != pos->second.end(); ++itr)
    {

        SingleProperty<Owner,IOType> *ptr = 
          static_cast<SingleProperty<Owner,IOType>*>(itr->second);
        (value->*(ptr->m_Getter))(); // return IOType discarded?!?!
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读