C++ 仿函数回调设置

标签 c++ callback handler functor

我正在关注 Lars Haendel 的 Functor tutorial在 newty.de 上设置回调系统。然而,我有点困惑,我希望有人能帮助我。

这是我的 Functor 模板

#include <igameevents.h>

// Abstract Base Class (Functor)
class TBaseCallback
{
public:

    // two possible functions to call member function. virtual cause derived
    // classes will use a pointer to an object and a pointer to a member function
    // to make the function call
    virtual void operator()(IGameEvent *pEvent){};  // call using operator
    virtual void Call(IGameEvent *pEvent) {};       // call using function
};


// Derived Template Class
template <class TClass> class TEventCallback : public TBaseCallback
{
private:

    void (TClass::*funcPtr)(IGameEvent*);       // pointer to member function
    TClass* thisPtr;                            // pointer to object

public:

    // constructor - takes pointer to an object and pointer to a member and stores them in two private variables
    TEventCallback(TClass* _thisPtr, void(TClass::*_funcPtr)(const char*))
    { thisPtr = _thisPtr;  funcPtr=_funcPtr; };

    // override operator "()"
    virtual void operator()(IGameEvent *pEvent)
    { (*thisPtr.*funcPtr)(pEvent); };           // execute member function

    // override function "Call"
    virtual void Call(IGameEvent *pEvent)
    { (*thisPtr.*funcPtr)(pEvent); };           // execute member function
};

我想做的基本上是允许其他 .dll 使用我的 HookGameEvent() 函数,当调用游戏事件时,我可以运行我的 Hook vector ||列表,检查事件名称是否匹配,然后根据需要执行回调。令我困惑的是如何将回调存储在我的 HookEvent 结构中,如下所示。

std::vector<EventHook*> m_EventHooks;

struct EventHook
{
    char *name;
    EventHookMode mode;
    //TEventCallback<IGameEvent*> pEventCallback;
};

我现在已经将它注释掉了,但我确信它很明显我混淆了什么以及我在哪里搞砸了。如果有人可以提供任何帮助,我们将不胜感激。

最佳答案

大多数人不了解继承。通常,派生类是实现细节。你唯一一次说出他们的名字是为了构建它们。此外,基类中的虚函数应该是私有(private)的和纯的,并且在派生类中应该是完全不可访问的,这是 C++ 中的一个设计错误,没有强制执行。

struct TBaseCallback
    void operator()(IGameEvent *pEvent) { _Call(pEvent); }; 
    void Exec(IGameEvent *pEvent) { _Call(PEvent); }
private:
    virtual void _Call(IGameEvent *pEvent)=0;
};

struct EventHook
{
    char *name;
    EventHookMode mode;
    TBaseCallback *p;
    void dispatch(char *msg; IGameEvent *e) const { 
      if(strcmp(msg,name)==0) p->Exec(e); 
   }
};

通过这种设计,从 TBaseCallback 派生的类中的内容没有任何区别,也不应该有任何区别。只有抽象应该永远是公开可见的。在普通代码中,这很难强制执行。当您使用 DLL 获取派生类时,这是绝对强制性的,因为派生类集是开放的/任意的/无限的/不确定的(由您选择)。

顺便说一句:当您将其推向更复杂的抽象时,您很快就会发现为什么面向对象是一个错误的概念。对于加载 DLL 的派生类,您不能使用 dynamic_cast 开关作弊(因为它们是封闭的/特定的/有限的/确定的)。

关于C++ 仿函数回调设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4282404/

相关文章:

Matlab:绘制点并使它们可点击以显示有关它的信息

jquery - 如何从jquery回调fnc返回数据?

C++ 使用参数调用不带参数的回调 - 或者更好的解决方案

header - 访问 JAX-WS 自定义处理程序中的安全 header

c# - 将参数传递给事件处理程序

c++ - 与不使用 if 的测试相比,if 语句的效率如何? (C++)

c++ - LDAP SASL 绑定(bind) C++

c++ - Visual Studio 2010 Qt 插件 Cmake 项目

android - 如何刷新处理程序中的待处理消息和回调

c++ - 开源 FIX 客户端模拟器