使用函数指针作为成员函数的代理
Use function-pointer as proxy to member-function
假设 class 像这样:
class Speaker {
public:
void (*saySomething)();
}
关键是我们可以实例化 class 并调用存储的函数指针,以便让它说些什么(无论结果是什么)。这种方法的背景是让实际函数驻留在共享库中,并且 Speaker
充当某种包装器 class (函数在库中解析,指针被分配给变量在 class) 中。
现在考虑我们有另一个 class 扩展 Speaker
:
class ConstantSpeaker : public Speaker {
protected:
std::string message;
void doSpeak();
}
方法的实现如下:
ConstantSpeaker::doSpeak() {
std::cout << message << std:endl;
}
现在我想以某种方式分配 saySomething
指针,以便调用以某种方式重新路由到 ConstantSpeaker::doSpeak()
。然而,这不可能直接实现,因为 doSpeak()
是一个成员函数,而 saySomething
是一个指向非成员函数的指针。
我的另一个想法是创建 doSpeak()
作为 ConstantSpeaker
的友元函数。然后指针分配工作正常,但现在 doSpeak()
需要将实际消息作为参数保存的对象才能访问消息。
对我来说,似乎应该有一种(或多或少)直接的方式来做这件事,因为我只能在拥有 Speaker
的实例时调用 Speaker::saySomething
在眼前。因此,相应对象的可用性应该不是问题,但我仍然无法弄清楚如何分配该指针。
我能想出的唯一解决方案是添加一个 public virtual Speaker::doSaySomething
函数,其实现将调用函数指针(不再是 public 以防止miss-usage) 并且可以被 ConstantSpeaker
覆盖以调用 ConstantSpeaker::doSpeak()
代替。
这个问题还有其他解决方案吗?
另一种解决方案就是使用标准的std::function<void()>
,然后它仍然可以声明为public。
此外,您可以使用指向成员函数的指针而不是裸函数指针,但在基类中使用它时要注意切片 class。
但是,我认为最简单的方法就是使用 virtual
函数,就像您提到的那样。
也许可以多说说你的背景?你要解决的问题是什么?
假设 class 像这样:
class Speaker {
public:
void (*saySomething)();
}
关键是我们可以实例化 class 并调用存储的函数指针,以便让它说些什么(无论结果是什么)。这种方法的背景是让实际函数驻留在共享库中,并且 Speaker
充当某种包装器 class (函数在库中解析,指针被分配给变量在 class) 中。
现在考虑我们有另一个 class 扩展 Speaker
:
class ConstantSpeaker : public Speaker {
protected:
std::string message;
void doSpeak();
}
方法的实现如下:
ConstantSpeaker::doSpeak() {
std::cout << message << std:endl;
}
现在我想以某种方式分配 saySomething
指针,以便调用以某种方式重新路由到 ConstantSpeaker::doSpeak()
。然而,这不可能直接实现,因为 doSpeak()
是一个成员函数,而 saySomething
是一个指向非成员函数的指针。
我的另一个想法是创建 doSpeak()
作为 ConstantSpeaker
的友元函数。然后指针分配工作正常,但现在 doSpeak()
需要将实际消息作为参数保存的对象才能访问消息。
对我来说,似乎应该有一种(或多或少)直接的方式来做这件事,因为我只能在拥有 Speaker
的实例时调用 Speaker::saySomething
在眼前。因此,相应对象的可用性应该不是问题,但我仍然无法弄清楚如何分配该指针。
我能想出的唯一解决方案是添加一个 public virtual Speaker::doSaySomething
函数,其实现将调用函数指针(不再是 public 以防止miss-usage) 并且可以被 ConstantSpeaker
覆盖以调用 ConstantSpeaker::doSpeak()
代替。
这个问题还有其他解决方案吗?
另一种解决方案就是使用标准的std::function<void()>
,然后它仍然可以声明为public。
此外,您可以使用指向成员函数的指针而不是裸函数指针,但在基类中使用它时要注意切片 class。
但是,我认为最简单的方法就是使用 virtual
函数,就像您提到的那样。
也许可以多说说你的背景?你要解决的问题是什么?