繁体   English   中英

RAD Studio c++ 模板通用事件拦截器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM