如何:Class 函数指针 (C++)

HOW TO: Class functions pointers (C++)

我在理解函数指针方面遇到了一些问题。尽管我已经阅读了很多关于此的主题,但我仍然对以下案例有疑问。

我的示例很简单 - 我有一个操纵杆 class,它有一些函数指针以及可以分配这些指针的函数,但我不知道如何正确执行此操作。

我会尽量保持简单:

class Joystick {
    void (Player::*OnShootKeyPressed)();  // pointer that takes no arguments and returns nothing

    void SetCallback(void (Player::*f)) {
       OnShotKeyPressed = f;
    }
}

class Player {
   void OnShootAction() { ...do the shooting...}

   void Initialize() {
      Joystick* joy = pInputMng->GetJoystick();

      joy->SetCallback( &Player::OnShootAction() );
   }
}

--根据Captain Obvlious评论编辑--

这是我想要实现的一个简短示例,但我似乎没有正确理解这些函数指针。我做错了什么?

在此先感谢大家的帮助!

更正代码和答案

1.) 我遇到了问题中未提及的命名空间的一些问题,因此我无法创建函数。

两个类都在命名空间下,所以分配函数指针的函数被拒绝了:

void                        SetCallback(void (ehJoystick::*f)())

必须改为:

void                        SetCallback(void (eg::ehJoystick::*f)())

但是,编译器不接受前面的命名空间。我以为我在其他地方做错了,但问题一直都在那里。

2.) 我不知道您需要一个对象引用来调用成员函数指针。以下代码正确且有效。

class Joystick {
    Player* pPlayer;
    void (Player::*OnShootKeyPressed)() = NULL;  // pointer that takes no arguments and returns nothing

    void SetCallback(void (Player::*f)(), Player *p) {
        OnShotKeyPressed = f;
        pPlayer = p; // we need a reference to the object
    }
    void OnKeyPressed(key) {
        if( key == SHOOT && OnShootKeyPressed != NULL ) {
            (pPlayer->*OnShootKeyPressed)(); //that's how the function is called
        }
    }

class Player {
    void OnShootAction() { ...do the shooting...}

    void Initialize() {
    Joystick* joy = pInputMng->GetJoystick();

    joy->SetCallback( &Player::OnShootAction, this );
}

我喜欢函数指针。我认为他们是我最好的私人朋友。但这可能不是他们的时候。当整个对象来回调用时,只需传递对象即可。

如果你需要对象之间更好的解耦,构建一个接口。我会选择接口路由,因为为什么不呢?一旦你看到了困难的方法,简单的方法就容易了。

首先,为操纵杆的用户定义一个接口

class ButtonUser
{
    virtual void OnShootAction() = 0; // function to be implemented by children
    virtual void OnJumpAction() = 0; 
    virtual void OnDeathBlossomAction() = 0; 
    ...
}

现在是一个使用按钮界面的操纵杆,对播放器一无所知

class Joystick {
    ButtonUser * pUser;

    void SetCallback(ButtonUser * puser) {
        pUser = puser;
    }
    void OnKeyPressed(key) {
        if (pUser != NULL) {
            switch( key ) {
                 case SHOOT: 
                     pUser->OnShootAction(); 
                     break;
                 case JUMP: 
                     pUser->OnjumpAction(); 
                     break;
                 case DB: 
                     pUser->OnDeathBlossomAction(); 
                     break;
                 ...
            }
        }
    }
}

并且 Player 将自己安装为 Joystick 的用户

class Player: public ButtonUser{
    void OnShootAction() { ...do the shooting...}
    void OnJumpAction() {...jump...}; 
    void OnDeathBlossomAction() {...blow $#!+ up!...}
    ...

    void Initialize() {
    Joystick* joy = pInputMng->GetJoystick();

    joy->SetCallback( this );
}