void函数指针的二维数组c ++
Posted
技术标签:
【中文标题】void函数指针的二维数组c ++【英文标题】:Two-dimensional array of void function pointers c++ 【发布时间】:2014-11-21 06:47:33 【问题描述】:我正在尝试在 2 台计算机“玩家”之间构建一个高效的 Rock、Paper、Scissors 模拟器。我看到here 的一个建议是使用矩阵来存储可能的结果。我真的很喜欢这个想法,因为这意味着我不必有 9 个不同的 if() 语句来解释所有可能的值。每当一场比赛完成时,我都有函数来迭代每个玩家的赢、输和平局的数量。因此,我认为如果我可以构建一个函数指针的二维数组,这样 [0][0] 代表双方抛出“Rock”并导致 Draw,抛出函数 addDraw( ) 为每个玩家。我找到了一个函数指针的一维数组的示例,它可以工作here。
当我尝试编译时,我的代码抛出了几个错误。如果还需要什么,请告诉我。
调用结果的函数:
void Player::result(vector<Player*> &vals, int x, int y)
Player *p1 = vals[0];
Player *p2 = vals[1];
void(*results1[3][3]) =
p1->addDraws, p1->addWins, p1->addLosses ,
p1->addLosses, p1->addDraws, p1->addWins ,
p1->addWins, p1->addLosses, p1->addDraws
;
添加赢、输和平的功能:
void Player::addWins()
wins++;
void Player::addLosses()
losses++;
void Player::addDraws()
draws++;
所有函数都在 Player.h 中初始化并在 Player.cpp 中声明(我认为这是正确的术语)。我收到的最常见错误是“错误 C2440: 'initializing' : cannot convert from 'void (__thiscall Player::* )(void)' to 'void *'
【问题讨论】:
所有函数都在 Player.h 中声明并在 Player.cpp 中定义。这是正确的。 您声明了一个指向void
的3x3 指针数组,您的意思可能是void(Player::* results1[3][3])();
(假设函数不是static
)。如果你真的想在不失去理智的情况下走这条路,你应该首先typedef
成员函数指针类型。使用指针时,您还需要提供一个对象。
【参考方案1】:
你有一个 void 指针数组,不是函数指针,成员函数也不是函数指针。
你需要类似的东西
typedef void (Player::*Score)(); // typedefs and function types go together well
Score scores[3][3]) =
&Player::addDraws, &Player::addWins, &Player::addLosses ,
&Player::addLosses, &Player::addDraws, &Player::addWins ,
&Player::addWins, &Player::addLosses, &Player::addDraws
;
// Calling
Player a;
(a.*scores[0][0])();
或者,使用这样的免费函数:
void addWins(Player* p)
p->addWins();
// Similar for the others...
typedef void (*Score)();
Score scores[3][3] = addWins, ....
//
Player* player = ...
scores[0][0].addWins(player);
或者,你可以是现代人并使用std::function
。
【讨论】:
我希望我在使用 c++ 方面足够成熟,知道如何使用 std:function。 一直在互联网上寻找相关问题的解决方案,这是最简单的一个,从长远来看(并且也有效)。我已经省略了 typedef,因为我发现它是多余的。【参考方案2】:void (*results1[3][3]) =
p1->addDraws, p1->addWins, p1->addLosses ,
p1->addLosses, p1->addDraws, p1->addWins ,
p1->addWins, p1->addLosses, p1->addDraws ;
我觉得应该是这样的
void (*results1[3][3])() =
p1->addDraws, p1->addWins, p1->addLosses ,
p1->addLosses, p1->addDraws, p1->addWins ,
p1->addWins, p1->addLosses, p1->addDraws ;
或者,你可以使用 typedef
typedef void (*func)();
func results1[3][3] =
p1->addDraws, p1->addWins, p1->addLosses ,
p1->addLosses, p1->addDraws, p1->addWins ,
p1->addWins, p1->addLosses, p1->addDraws ;
【讨论】:
谢谢,傅敏。虽然仍然抛出:错误 C2440: 'initializing' : cannot convert from 'overloaded-function' to 'void (__cdecl *)(void)'【参考方案3】:在 C++ 中,方法不是函数。如果您的计数器在类实例中,则调用的代码需要知道this
才能执行。
解决问题有几种方法:
不要使用void (*)()
函数,而是使用void (*)(MyClass *)
并将要更新的实例传递给函数
使用指向成员的指针。这在引擎盖下基本相同,但语法有点奇怪;类型是void (MyClass::*)()
,要使用成员指针进行调用,语法将使用奇怪的->*
运算符,例如(this->*m[i][j])()
。
使用闭包。这需要 C++11 并且从语法的角度来看更简洁;而不是使用指向函数的指针矩阵,而是使用捕获对象实例的std::function<void()>
对象矩阵。 C++ 闭包无法处理向上的 funarg 问题,但在您的情况下,这应该不是问题(在我看来,不需要让其中一个闭包在持有计数器的实例中幸存下来)。
然而,在非常具体的情况下,我根本不会使用指向函数的指针,而是使用带有结果 (0, 1, 2) 的整数矩阵,然后更新结果代码只是
results[m[i][j]]++;
没有if
s,也没有涉及电话。在这个想法中,results
是一个由三个整数组成的数组,其中包含 A 获胜、B 获胜和平局的计数器。
【讨论】:
以上是关于void函数指针的二维数组c ++的主要内容,如果未能解决你的问题,请参考以下文章
请问 对于指向函数的指针,前面的括号(int (*)(void*,void*))代表啥呢?谢谢