gpt4 book ai didi

c++ - 在 C++ 中处理指向层次结构中成员函数的指针

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

我正在尝试对以下情况进行编码:我有一个基类提供处理事件的框架。我正在尝试为此使用指向成员函数的指针数组。它是这样的:

class EH { // EventHandler
virtual void something(); // just to make sure we get RTTI
public:
typedef void (EH::*func_t)();
protected:
func_t funcs_d[10];
protected:
void register_handler(int event_num, func_t f) {
funcs_d[event_num] = f;
}
public:
void handle_event(int event_num) {
(this->*(funcs_d[event_num]))();
}
};

然后用户应该从这个派生其他类并提供处理程序:

class DEH : public EH {
public:
typedef void (DEH::*func_t)();
void handle_event_5();
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
........
}
};

此代码无法编译,因为 DEH::func_t 无法转换为 EH::func_t。这对我来说很有意义。在我的例子中,转换是安全的,因为 this 下的对象实际上是 DEH。所以我想要这样的东西:

void EH::DEH_handle_event_5_wrapper() {
DEH *p = dynamic_cast<DEH *>(this);
assert(p != NULL);
p->handle_event_5();
}

然后代替

     func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile

在 DEH::DEH() 中把

     register_handler(5, &EH::DEH_handle_event_5_wrapper); 

所以,最后的问题(花了我足够长的时间...):有没有办法自动创建这些包装器(如 EH::DEH_handle_event_5_wrapper)?或者做类似的事情?对于这种情况,还有哪些其他解决方案?

谢谢。

最佳答案

无需为所有派生类中的每个处理程序创建一个包装器(当然,这甚至不是一种可行的方法),您可以简单地使用 static_cast 来转换 DEH::func_tEH::func_t。成员指针是逆变:它们自然向下转换层次结构,并且可以使用 static_cast 手动向上转换层次结构(与普通对象指针相反,后者是协变)。

您正在处理的情况正是扩展 static_cast 功能以允许成员指针向上转换的原因。此外,成员函数指针的非平凡内部结构也是专门以这种方式实现的,以正确处理这种情况。

所以,你可以简单地做

DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, static_cast<EH::func_t>(f5));
........
}

我会说,在这种情况下,定义类型定义名称 DEH::func_t 毫无意义 - 它毫无用处。如果删除 DEH::func_t 的定义,典型的注册代码将如下所示

DEH() {
func_t f5 = static_cast<func_t>(&DEH::handle_event_5);
// ... where `func_t` is the inherited `EH::func_t`
register_handler(5, f5);
........
}

为了让它看起来更优雅,您可以在 DEH 中为 register_handler 提供一个包装器,或者使用其他方式(宏?模板?)来隐藏转换。

此方法不会为您提供任何方法来验证调用时处理程序指针的有效性(正如您可以在基于包装的版本中使用 dynamic_cast 所做的那样)。我不知道你有多关心这张支票到位。我想说,在这种情况下,它实际上是不必要的和过度的。

关于c++ - 在 C++ 中处理指向层次结构中成员函数的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2916285/

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