来自不同 类 的 C++ 多个回调成员函数,没有 std 和 boost
C++ multiple callback member functions from different classes without std and boost
我是 C++ 的新手,我不想使用任何库,因为我想真正了解内部发生的事情。
此外,我尽量保持我的库使用率尽可能低(以提高性能和)使其尽可能独立于平台(不导出库)。
所以总而言之,我不想使用 std 或 boost 来解决这个问题。
我的问题:
我有一个具有以下功能的 EventHandler:
template<class T> void EventHandler::SetCallbackFunction(T* obj, void (T::*mem_fkt)(void));
我必须保存对象和函数以便稍后调用它。
有两种可能性:
- EventHandler 作为模板 class(和 typedef)
- void* -> 但要调用该函数,我需要将其转换回去,为此我需要 classname :/
为什么这些不起作用:
- EventHandler 不能是模板 class 因为它需要处理多个 classes..
- void* -> 我不知道如何保存 class 名称以便稍后在
上使用
我该怎么做?
(或者有其他方法吗?也许有一种方法可以保存 class 名称以便稍后使用?)
编辑:
此外,我可能需要为每个 class 注册多个回调函数,因此接口并不是一个真正的选项。
class A {
public:
void CallbackFktForEventHandler();
void CallbackFktForAnimationHandler();
etc...
};
而且我知道您可以根据以下内容解决它:
class A{
public:
void Callback();
static void CallbackStatic(void* self){
static_cast<A*>->CallBack();
};
};
但这对我的口味来说太限制了。
您可以使用类型擦除。通过实例化实现非模板虚拟接口的 class 模板,您可以有效地保存 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
,您可以自己滚动或使用邪恶的原始拥有指针。
你可以试试这个:
创建一个(纯虚拟)base-class,只有一个函数call()
:
class Function{
virtual void call()=0;
}
创建一个模板化的 class,它存储一个函数指针和一个对象,并使其继承自 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()
但如果您至少使用标准库,您的生活会轻松很多。基本上我会使用 std::bind 将您的对象和您的成员函数绑定到一个函数 void()(void) 中,然后将这些对象存储在 std::vector.
中
编辑:Oktalist 更快;)
我是 C++ 的新手,我不想使用任何库,因为我想真正了解内部发生的事情。
此外,我尽量保持我的库使用率尽可能低(以提高性能和)使其尽可能独立于平台(不导出库)。
所以总而言之,我不想使用 std 或 boost 来解决这个问题。
我的问题:
我有一个具有以下功能的 EventHandler:
template<class T> void EventHandler::SetCallbackFunction(T* obj, void (T::*mem_fkt)(void));
我必须保存对象和函数以便稍后调用它。
有两种可能性:
- EventHandler 作为模板 class(和 typedef)
- void* -> 但要调用该函数,我需要将其转换回去,为此我需要 classname :/
为什么这些不起作用: - EventHandler 不能是模板 class 因为它需要处理多个 classes.. - void* -> 我不知道如何保存 class 名称以便稍后在
上使用我该怎么做?
(或者有其他方法吗?也许有一种方法可以保存 class 名称以便稍后使用?)
编辑:
此外,我可能需要为每个 class 注册多个回调函数,因此接口并不是一个真正的选项。
class A {
public:
void CallbackFktForEventHandler();
void CallbackFktForAnimationHandler();
etc...
};
而且我知道您可以根据以下内容解决它:
class A{
public:
void Callback();
static void CallbackStatic(void* self){
static_cast<A*>->CallBack();
};
};
但这对我的口味来说太限制了。
您可以使用类型擦除。通过实例化实现非模板虚拟接口的 class 模板,您可以有效地保存 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
,您可以自己滚动或使用邪恶的原始拥有指针。
你可以试试这个:
创建一个(纯虚拟)base-class,只有一个函数call()
:
class Function{
virtual void call()=0;
}
创建一个模板化的 class,它存储一个函数指针和一个对象,并使其继承自 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()
但如果您至少使用标准库,您的生活会轻松很多。基本上我会使用 std::bind 将您的对象和您的成员函数绑定到一个函数 void()(void) 中,然后将这些对象存储在 std::vector.
中编辑:Oktalist 更快;)