[英]RAD Studio c++ template generic event blocker
我一直遇到 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);
// ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.