有没有办法在不改变参数的情况下改变回调的范围?

时间:2013-07-28 19:36:32

标签: c++ callback

我正在使用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 (*)()"

错误

2 个答案:

答案 0 :(得分:1)

你需要制作一个“包装”功能。但是,这里的问题是你还需要能够找到你想要“完成”的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中的值。

答案 1 :(得分:1)

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

但是,由于您的musicFinished方法目前可用作独立功能,因此可能不需要访问CMusic的{​​{1}}或protected成员,你努力限制其范围可能意味着你不希望其他东西称之为它,我个人会将你的private函数保留为独立但将其声明为musicFinished(或将其移动到匿名命名空间) ,如果您愿意,可以在static来源(CMusic.cpp)文件中。这样做会将其范围限制为源文件(“编译单元”)。优于.ccprivate类方法的一个优点是它不需要在头文件中公开,因此它在某种意义上更加私密。