C++函子回调设置
我正在按照 Lars Haendel 在 newty.de 上的Functor 教程来设置回调系统。但我有点困惑,我希望有人可以帮助我。
这是我的 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() 函数,当调用游戏事件时,我可以运行我的钩子的向量 || 列表,检查事件名称是否匹配,然后根据需要执行回调。但令我困惑的是如何将回调存储在我的 HookEvent 结构中,如下所示。
std::vector<EventHook*> m_EventHooks;
struct EventHook
{
char *name;
EventHookMode mode;
//TEventCallback<IGameEvent*> pEventCallback;
};
我现在已经把它注释掉了,但我确信我困惑的地方以及我搞砸的地方很明显。如果有人可以提供任何帮助,我们将不胜感激。
Im following Lars Haendel's Functor tutorial on newty.de to setup a callback system. I am a bit confused however and I am hoping someone can assist me.
Here is my Functor template
#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
};
What I want to do is basically allow other .dlls to use my HookGameEvent() function, and when a Game Event is called, I can run through a vector||list of my hooks, check if the event name matches, then execute the callbacks as needed. What is confusing me though is how I can store the callback in my HookEvent struct which looks like this.
std::vector<EventHook*> m_EventHooks;
struct EventHook
{
char *name;
EventHookMode mode;
//TEventCallback<IGameEvent*> pEventCallback;
};
I have it commented out for now, but im sure its obvious what im confused on and where I am screwing up. If anyone can provide any assistance it would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
大多数人不了解继承。一般来说,派生类是实现细节。你唯一一次说出它们的名字就是构建它们。此外,基类中的虚拟函数应该是私有的和纯的,并且在派生类中应该完全不可访问,这是 C++ 中的一个设计错误,没有强制执行。
通过这种设计,从 TBaseCallback 派生的类中的内容没有任何区别,也不应该有任何区别。只有抽象应该是公开可见的。在普通代码中,这很难强制执行。当您使用 DLL 获取派生类时,这是绝对强制的,因为派生类集是开放/任意/无限/不确定的(任您选择)。
顺便说一句:当您将其推向更复杂的抽象时,您很快就会发现为什么面向对象是一个破碎的概念。使用 DLL 加载的派生类,您无法使用dynamic_cast 开关进行欺骗(因为它们是封闭的/特定的/有限的/确定的)。
Most people don't understand inheritance. Generally, derived classes are implementation details. The only time you utter their names are to construct them. Furthermore, virtual functions in a base should be private and pure, and should be completely inaccessible in derived classes, it's a design bug in C++ that this isn't enforced.
With this design, it doesn't make any difference what is in classes derived from TBaseCallback, and nor should it. Only the abstraction should ever be publically visible. In normal code this is hard to enforce .. when you're using DLLs to get the derived classes it is absolutely mandatory because the set of derived classes is open/arbitrary/infinite/indeterminate (take your pick).
BTW: when you push this to more complex abstractions you will soon discover why Object Orientation is a broken concept. With DLL loaded derived classes, you simply cannot cheat with dynamic_cast switches (because they're closed/specific/finite/determinate).
将执行回调的类应该保存要调用的 Functor 对象的列表。 然后
现在,EventHook 应该有一个虚函数:
每个有兴趣获得通知的人都将创建自己的钩子实现:
通过多态性的奇迹,当您迭代 m_EventHooks 容器的所有元素并调用 < code>notifyMe() 对于这些,将调用正确的类版本。
The class that is going to do the callbacks should hold a list of Functor objects to be called. These would be your
Now the EventHook should have a virtual function:
Then everyone that is interested in getting notified will create his own implementation of the hook:
Through the wonders of polymorphism, when you then iterate over all elements of your m_EventHooks container and call
notifyMe()
for those, the correct class' version will be called.我看到的问题(很可能还有其他问题)是,在 pEventCallback 的类型中,模板参数应该是类类型,但实际上是指针类型。一种解决方法(不限制回调包装的类型)是使用基本类型:
如果
TEventCallback
的 API 有更多内容,并且需要通过EventHook
访问它,您应该将TEventCallback
中处理对象及其方法的代码移至单独的子类中。题外话
您不妨将
TBaseCallback::Call
的默认实现调用TBaseCallback::operator()
。The problem I see (and there could very well be others) is that in
pEventCallback
's type, the template parameter should be a class type but is actually a pointer type. One fix (without limiting what types the callback wraps) is to use the base type:If there's more to
TEventCallback
's API, and it needs to be accessible through anEventHook
, you should move the code inTEventCallback
that deals with an object and its method into a separate subclass.Off-Topic
You might as well make the default implementation of
TBaseCallback::Call
callTBaseCallback::operator()
.我认为您会遇到复杂的编译器错误,因为您在模板实例化中使用 T* 而不是 T。
试试这个:
应该编译,如果那是你想要的。
I think you will be getting a complicated compiler error because you are using T* instead of T in your template instantiation.
Try this:
should compile, if that what you want.