如何: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 );
}
我在理解函数指针方面遇到了一些问题。尽管我已经阅读了很多关于此的主题,但我仍然对以下案例有疑问。
我的示例很简单 - 我有一个操纵杆 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 );
}