有没有任何方法可以在不更改参数的情况下更改回调的范围

Is there any way to change the scope of a callback without changing the paramaters?

本文关键字:参数 情况下 范围 回调 方法 任何 有没有      更新时间:2023-10-16

我使用的是SDL2_mixer库,但我认为这个问题也适用于一般情况。

目前,我想使用的函数Mix_HookMusicFinished(void (*music_finished)(void))有一个到C风格函数全局范围的集合回调。但是,我希望将该回调设置为我自己的类void CMusic::musicFinished()中的成员函数,而不需要全局范围内的函数。

有办法这样做吗?像Mix_HookMusicFinished(musicFinished)这样的东西会很好,但它直接有一个argument of type "void (CMusic::*)()" is incompatible with parameter of type "void (*)()" 的错误

您需要创建一个"包装器"函数。然而,这里的问题是,你还需要能够找到你想要"完成"的CMusic对象——这才是的关键所在

类型为的参数。。。与不兼容。。。

都是关于。由于无法将参数传递给musicFinished对象,因此需要其他方法来"查找"CMusic对象。

如果我们假设有一种方法可以做到这一点,那么这样的方法就会奏效:

class CMusic 
{
   ... 
 public:
   ...
   static void musicFinishedWrapper();
   void musicFinished();
   ...
};

void CMusic::musicFinishedWrapper()
{
   CMusic* music = getTheMusicSomehow();   // No idea how you do this - depends on your code. 
   music->musicFinished();
}

你必须有一个CMusic对象的原因是你的musicFinished需要一个(隐藏的)this指针参数——这是我的小函数中music的值。

您可以将musicFinished移动到CMusic类中,并将其声明为static类方法。static类方法不在对象上调用;因此,它们没有用于指定this指针值的隐式参数,因此它们可以具有与独立函数相同的签名。您还可以将其设为private,以防止除CMusic之外的任何东西使用它。

然而,由于您的musicFinished方法目前是一个独立函数,因此可能不需要访问CMusicprotectedprivate成员,并且由于您限制其范围的努力可能意味着您不希望其他东西调用它,我个人会将您的musicFinished函数保留为独立函数,但在CMusic源(.cpp.cc)文件中将其声明为static(或将其移动到匿名命名空间,如果您愿意的话)。这样做会将其范围限制在源文件("编译单元")。与privatestatic类方法相比,一个优点是它根本不需要在头文件中公开,因此在某种意义上它更私有。

相关文章: