如何解决RAD Studio C++ 模板通用事件拦截器
我一直在使用 RAD Studio XE 组件触发级联事件时遇到问题 - 例如当组件 A 的代码修改更改了组件 B 的内容,从而触发了组件 C 的更改等。 长话短说 - 通过 RAII 模式创建了一些阻塞机制。其中有多个,具体取决于我需要阻止的事件类型,例如 OnSelect 或 OnChange:
template<typename T,typename N>
class TOnChangeEventBlocker
{
public:
TOnChangeEventBlocker(T* object)
:m_pObject(object),m_pNotifyEvent(object->OnChange)
{
if (m_pObject)
{
m_pObject->OnChange = NULL;
}
}
~TOnChangeEventBlocker()
{
if (m_pObject)
{
m_pObject->OnChange = m_pNotifyEvent;
}
}
private:
T* const m_pObject;
N m_pNotifyEvent;
};
有没有办法让它更通用?让它与 __property 公开的私有事件处理程序一起工作?
与其编写过多的事件阻止程序,不如使用:一个、简单、通用的 TEventBlocker。
m_pObject->/*something here*/ = m_pNotifyEvent;
这是一个遗留代码和 RAD Studio XE 项目 - 没有太多的 c++11。
我跟随@Jarod42 成员指针的踪迹,面包屑引导我找到最终解决方案:
template <typename T>
class TEventBlocker
{
public:
TEventBlocker(T* f)
: eventFunctionClassMember(f),eventFunction(NULL)
{
if (eventFunctionClassMember && *eventFunctionClassMember)
{
eventFunction = *eventFunctionClassMember;
*eventFunctionClassMember = NULL;
}
}
~TEventBlocker()
{
if (eventFunctionClassMember)
{
*eventFunctionClassMember = eventFunction;
}
}
private:
T* eventFunctionClassMember;
T eventFunction;
};
调用它(必须明确模板参数):
TEventBlocker<Classes::TNotifyEvent> blockSelect(&(SelectComponent->OnSelect));
解决方法
看来你只需要拿会员:
template <typename T>
class EventBlocker
{
public:
EventBlocker(T& event)
:m_event(event),m_old(event)
{
m_event = NULL; // nullptr; in C++11
}
~EventBlocker()
{
m_event = m_old;
}
private:
EventBlocker(const EventBlocker&); // = delete; in C++11
EventBlocker& operator=(const EventBlocker&); // = delete; in c++11
private:
T& m_event;
T m_old;
};
// C++17 CTAD would be enough,but before:
template <typename T>
EventBlocker<T> make_EventBlocker(T& event) { return {event}; }
然后:
auto eventBlocker = make_EventBlocker(myObject->OnChange);
// ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。