我有一个应用程序,当监视对象中发生硬件事件时,需要将对象的一个或多个成员函数用作回调。回调不需要参数。
通常我会使用boost或标准库函数(std :: function,std :: bind)来包装要调用的成员函数,但我不能使用它们,因为它们(boost,C ++ 11)不受支持或允许在平台上。我不确定效率,但这不是主题。
简而言之,我编写了一个类(MonitorSwi)来生成一个等待硬件事件的线程。创建对象时将配置硬件事件和回调,以便许多其他对象(如下面的DeviceManager)可以使用此封装功能。
除了使用bind之外,另一种方法是使基类具有由子对象实现的纯虚拟处理程序。然而,一些“设备管理器”'处理需要不同处理程序的多个SWI。
我目前使用的方法是拥有一个静态成员,该成员重定向到特定的对象实例并为SWI指定处理程序。
我写了一个简单的例子,删除了所有不必要的代码:
#include <iostream>
class MonitorSwi
{
public:
typedef void (*SwiHandlerFunc_t)(void*);
MonitorSwi(int id, void* pInstance, SwiHandlerFunc_t handler) :
m_id(id),
m_instance(pInstance),
m_handler(handler)
{
}
void HandleEvent()
{
std::cout << "MonitorSwi::HandleEvent() Handle SWI ID = " << m_id << std::endl;
(*m_handler)(m_instance);
}
private:
int m_id;
void* m_instance;
SwiHandlerFunc_t m_handler;
};
class DeviceManager
{
public:
DeviceManager() :
m_Swi1(1, this, HandleSwi1), // Register handler for SWI 1 events
m_Swi2(2, this, HandleSwi2) // Register handler for SWI 2 events
{
}
static void HandleSwi1(void* pInstance)
{
std::cout << "DeviceManager::HandleSwi1() Redirect to object..." << std::endl;
DeviceManager* ptr = reinterpret_cast<DeviceManager*>(pInstance);
ptr->HandleSwi1Member();
}
static void HandleSwi2(void* pInstance)
{
std::cout << "DeviceManager::HandleSwi2() Redirect to object..." << std::endl;
DeviceManager* ptr = reinterpret_cast<DeviceManager*>(pInstance);
ptr->HandleSwi2Member();
}
void HandleSwi1Member()
{
std::cout << "DeviceManager::HandleSwi1Member()" << std::endl;
// Process event that SWI 1 has signalled...
}
void HandleSwi2Member()
{
std::cout << "DeviceManager::HandleSwi2Member()" << std::endl;
// Process event that SWI 2 has signalled...
}
MonitorSwi m_Swi1;
MonitorSwi m_Swi2;
};
int main()
{
DeviceManager device;
// Fake hardware calling SWI 1 (normally performed by hardware event handler)
device.m_Swi1.HandleEvent();
// Fake hardware calling SWI 2 (normally performed by hardware event handler)
device.m_Swi2.HandleEvent();
return 0;
}
测试应用程序的输出:
MonitorSwi::HandleEvent() Handle SWI ID = 1
DeviceManager::HandleSwi1() Redirect to object...
DeviceManager::HandleSwi1Member()
MonitorSwi::HandleEvent() Handle SWI ID = 2
DeviceManager::HandleSwi2() Redirect to object...
DeviceManager::HandleSwi2Member()
我确信必须有一种方法可以使用模板来指定类类型以及在该类类型中声明的一个或多个成员函数处理程序。
是否有更有效或通用的方法来实现上述目标?
答案 0 :(得分:1)
您可以直接存储
typedef void (T::*SwiHandlerFunc_t)();
(对于作为T
的模板参数的MonitorSwi<T>
类型)并通过
(m_instance->*m_handler)();
完整代码位于此live example。