来自不同类的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, &A::CallbackFktForEventHandler); auto g = wrap(a, &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->call()
在线试用:http://ideone.com/3Hu5pw
但是,如果您至少使用标准库,您的生活会轻松很多。基本上我会使用 std::bind 将你的对象和你的成员函数绑定到一个函数 void()(void) 中,然后将这些对象存储在一个 std::vector 中。
编辑:Oktalist 更快 ;)
【讨论】:
感谢在线示例!我想为你的帖子投票,但我没有足够的声誉。以上是关于来自不同类的C++多个回调成员函数,没有std和boost的主要内容,如果未能解决你的问题,请参考以下文章