我试图创建一个事件处理系统,其中对象可以订阅其他对象广播的事件,并在广播该事件时调用方法。我试图实现这个单例类的 EventHandler 。对象调用 EventHandler 上的一个公共方法来订阅他们对某个对象广播的事件:
I'm trying to create an event handling system where objects can subscribe to events broadcasted by other objects and call a method when that event is broadcast. I'm trying to implement this with a singleton class called EventHandler. Objects call a public method on EventHandler that subscribes them to events broadcast by a certain object:
void startWatchingObjectEvent(PDObject * object, PDEvent event, PDObject* listener, PDReceiver receiver);PDObject 将由 EventHandler 处理的对象。 PDEvent 只是一个标识事件的唯一字符串。
PDObject is a base class for all the objects that will be handled by the EventHandler. PDEvent is simply a unique string that identifies the Event.
PDReceiver 是我碰到问题的地方。我有它typedef到 PDObject 类的方法指针:
PDReceiver is where I'm running into issues. I have it typedef'd to a method pointer on the PDObject class:
typedef void (PDObject::*PDReceiver)(PDObject*, PDEvent);现在 PDObject 真的有任何方法, EventHandler 将要调用,但派生类 PDObject 将会,我想创建一个通用类型 EventHandler 可以存储将应用于 PDObject 的任何派生类。我以这种方式实现了 EventHandler ,并尝试编写一个单元测试,以确保它工作正常:
Now the PDObject class itself doesn't really have any methods that EventHandler is going to call, but derived classes of PDObject will, and I wanted to create a generic type that EventHandler could store that would apply to any derived classes of PDObject. I implemented EventHandler this way and tried writing a unit test to make sure it's working okay:
const PDEvent Test_PokeEvent = "Test_PokeEvent"; void Test_EventHandler_sendObjectMessage() { EventHandler& eventh = EventHandler::instance(); Test_PDObject caster; Test_PDObject listener; PDReceiver receiver = &Test_PDObject::test_poke; eventh.startWatchingObjectEvent(&caster, Test_PokeEvent, &listener, (listener.*receiver)(&caster, Test_PokeEvent)); eventh.sendObjectEvent(&caster, Test_PokeEvent); assert(listener.test_wasPoked()); }Test_PDObject test_poke 时转换 wasPoked 位的 >
Test_PDObject is a derived class of PDObject that just flips a wasPoked bit when test_poke is called.
问题是,编译器不喜欢我尝试分配 Test_PDObject 到 PDReceiver 的方法,因为 PDReceiver 被定义为 PDObject 。
The issue is that the compiler doesn't like me trying to assign a method of Test_PDObject to the type PDReceiver since PDReceiver is defined as a method of PDObject.
我想要做的事情是否可能?我可以使用这个通用方法指针类型来引用派生类的方法吗?或者是我的方法完全有缺陷?
Is what I'm trying to do even possible? Can I use this generic method pointer type to refer to methods of derived classes? Or is my approach just entirely flawed?
编辑:我想出了我可以使用 static_cast 如下:
I figured out I can use static_cast to cast the method pointer of the derived class to a method pointer of the base class like so:
PDReceiver receiver = static_cast<PDReceiver>(&Test_PDObject::test_poke);到目前为止这么好!我的单元测试现在运行正常。
And so far so good! My unit tests are working perfectly now.
推荐答案一个 static_cast 类型 Child :: * 的指针到成员键入 Base :: * ,但请记住,如果您在 Base 的实例上意外使用指针到成员相关 Child )。
A static_cast is indeed all that is required to cast a pointer-to-member of type Child::* to type Base::*, but please remember that this might be quite dangerous if you by accident use the pointer-to-member on an instance of Base (and not the related Child).
尽管在类型 Base 的对象上调用 Child :: func 会导致 undefined-behavior ,因为我们正在访问函数内部Base的一个不存在的成员。
In the example below we use the same exact approach as described earlier, though calling Child::func on a object of type Base is causing undefined-behavior since we are accessing a non-existent member of Base inside the function.
struct Base { /* ... */ }; struct Child : Base { void func () { this->x = 123; } int x; };int main (int argc, char *argv[]) { typedef void (Base::*BaseFuncPtr) (); BaseFuncPtr ptr_to_child_func = static_cast<BaseFuncPtr> (&Child::func); Base b; (b.*ptr_to_child_func) (); /* undefined-behavior */ }
更多推荐
使用基类的通用方法指针来调用派生类的方法
发布评论