来自不同类的C++多个回调成员函数,没有std和boost

Posted

技术标签:

【中文标题】来自不同类的C++多个回调成员函数,没有std和boost【英文标题】:C++ multiple callback member functions from different classes without std and boost 【发布时间】:2016-05-09 05:46:47 【问题描述】:

我是 C++ 新手,我不想使用任何库,因为我想真正了解内部发生的事情。 此外,我尝试使我的库使用率尽可能低(以提高性能并)使其尽可能独立于平台(不导出库)。 所以总而言之,我不想使用 std 或 boost 来解决这个问题。

我的问题:

我有一个 EventHandler,它有一个函数:

template<class T> void EventHandler::SetCallbackFunction(T* obj, void (T::*mem_fkt)(void));

我必须保存对象和函数以便稍后调用它。 有两种可能:

EventHandler 作为模板类(和 typedef) void* -> 但要调用该函数,我需要将其转换回来,为此我需要类名:/

为什么这些不起作用: - EventHandler 不能是模板类,因为它需要处理多个类.. - void* -> 我不知道如何保存类名以便以后转换

我该怎么做? (或者还有其他方法吗?也许是一种保存类名以供以后转换的方法?)

编辑: 此外,我可能需要为每个类注册多个回调函数,因此接口并不是一个真正的选择。

class A 
 public:
   void CallbackFktForEventHandler();
   void CallbackFktForAnimationHandler();
   etc...
;

而且我知道你可以基于这样的方法来解决它:

class A
  public:
    void Callback();
    static void CallbackStatic(void* self)
      static_cast<A*>->CallBack();
    ;
;

但这对我的口味限制太多了。

【问题讨论】:

是什么让您觉得避免使用库对性能有好处? 重新编辑:没有什么能阻止你包装多个成员函数:auto f = wrap(a, &amp;A::CallbackFktForEventHandler); auto g = wrap(a, &amp;A::CallbackFktForAnimationHandler); 【参考方案1】:

您可以使用类型擦除。通过实例化实现非模板虚拟接口的类模板,您可以有效地保存obj 的类型。这基本上就是std::function 的实现方式,所以您只是在编写自己的std::function 的基本版本。

struct ICallback

    virtual void call() = 0;
;

template <class T>
struct Callback : public ICallback

    virtual void call() override  (m_obj->*m_func)(); 
    Callback(T *obj, void (T::*func)()) : m_obj(obj), m_func(func) 
    T *m_obj;
    void (T::*m_func)();
;

template <class T>
std::unique_ptr<ICallback> wrap(T *obj, void (T::*func)())

    return std::make_unique<Callback<T>>(obj, func);

如果您不想使用std::unique_ptr,您可以自己滚动或使用邪恶的原始拥有指针。

【讨论】:

好的,非常感谢,我会研究一下这种方法(就像我说我是 c++ 新手)【参考方案2】:

你可以试试这个:

创建一个只有一个函数的(纯虚拟)基类call()

class Function
  virtual void call()=0;

创建一个模板类,该类存储一个函数指针和一个对象,并使其继承自Function

template<typename T>
class TemplatedFunction
  void (T::*m_fkt)(void);
  T* m_obj;

  TemplatedFunction(T* obj, void (T::*fkt)(void)):m_fkt(fkt),m_obj(obj)

  void call
    (m_obj->*m_fkt)();
  

然后将指向Function 的指针存储在您的事件处理程序中,然后使用Function-&gt;call()

在线试用:http://ideone.com/3Hu5pw

但是,如果您至少使用标准库,您的生活会轻松很多。基本上我会使用 std::bind 将你的对象和你的成员函数绑定到一个函数 void()(void) 中,然后将这些对象存储在一个 std::vector 中。

编辑:Oktalist 更快 ;)

【讨论】:

感谢在线示例!我想为你的帖子投票,但我没有足够的声誉。

以上是关于来自不同类的C++多个回调成员函数,没有std和boost的主要内容,如果未能解决你的问题,请参考以下文章

不同类的成员函数指针的C++映射

什么类型可以保存 C++ 中不同类的成员函数指针?

没有可行的重载'='用于将std :: function回调赋值为成员函数

C++ 重载 == 比较来自不同类的对象

具有来自多个类的值的 C++ std::vector

使用 C++ 类成员函数作为 C 回调函数