gpt4 book ai didi

c++ - 使用基类的泛型方法指针调用派生类的方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:31:28 25 4
gpt4 key购买 nike

我正在尝试创建一个事件处理系统,其中对象可以订阅其他对象广播的事件,并在广播该事件时调用方法。我正在尝试使用一个名为 EventHandler 的单例类来实现它。对象调用 EventHandler 上的公共(public)方法,该方法将它们订阅到特定对象广播的事件:

void startWatchingObjectEvent(PDObject * object, PDEvent event, PDObject* listener, PDReceiver receiver);

PDObject 是将由 EventHandler 处理的所有对象的基类。 PDEvent 只是一个标识事件的唯一字符串。

PDReceiver 是我遇到问题的地方。我将其类型定义为 PDObject 类上的方法指针:

typedef void (PDObject::*PDReceiver)(PDObject*, PDEvent);

现在 PDObject 类本身实际上没有任何 EventHandler 将要调用的方法,但是 PDObject 的派生类将调用,我想创建一个 EventHandler 可以存储的通用类型,它适用于 PDObject 的任何派生类。我以这种方式实现了 EventHandler 并尝试编写单元测试以确保其正常工作:

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_PDObjectPDObject 的派生类,它在调用 test_poke 时仅翻转一个 wasPoked 位。

问题是编译器不喜欢我尝试将 Test_PDObject 的方法分配给 PDReceiver 类型,因为定义了 PDReceiver作为 PDObject 的方法。

我正在尝试做的事情是否可行?我可以使用这个泛型方法指针类型来引用派生类的方法吗?还是我的方法完全有缺陷?

编辑:我发现我可以使用 static_cast 将派生类的方法指针转换为基类的方法指针,如下所示:

PDReceiver receiver = static_cast<PDReceiver>(&Test_PDObject::test_poke);

到目前为止一切顺利!我的单元测试现在运行良好。

最佳答案

static_cast 确实是将类型为 Child::*pointer-to-member 转换为 所需的全部内容>Base::*,但请记住,如果您不小心在 Base 的实例上使用了pointer-to-member (而不是相关的 Child)。


在下面的示例中,我们使用与前面描述的完全相同的方法,尽管在 Base 类型的对象上调用 Child::func 会导致 undefined-行为,因为我们正在访问函数内 不存在 的 Base 成员。

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 */
}

关于c++ - 使用基类的泛型方法指针调用派生类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11487361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com