Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ void函数指针的二维数组c++;_C++_Arrays_Pointers - Fatal编程技术网

C++ void函数指针的二维数组c++;

C++ void函数指针的二维数组c++;,c++,arrays,pointers,C++,Arrays,Pointers,我正试图在两个电脑“玩家”之间建立一个高效的石头、布、剪刀模拟器。我看到的一个建议是使用矩阵来存储可能的结果。我非常喜欢这个想法,因为它意味着我不必使用9个不同的if()语句来解释所有可能的值。每当一场比赛结束,我都有函数来迭代每个球员的赢、输和平局次数。因此,我认为如果我可以构建一个二维函数指针数组,这样[0][0]代表双方的“石头”投掷,并将导致平局,为每个玩家投掷函数addDraw()。我发现了一个一维函数指针数组的例子,它可以工作 当我试图编译时,我的代码抛出了几个错误。如果还需要什么,

我正试图在两个电脑“玩家”之间建立一个高效的石头、布、剪刀模拟器。我看到的一个建议是使用矩阵来存储可能的结果。我非常喜欢这个想法,因为它意味着我不必使用9个不同的if()语句来解释所有可能的值。每当一场比赛结束,我都有函数来迭代每个球员的赢、输和平局次数。因此,我认为如果我可以构建一个二维函数指针数组,这样[0][0]代表双方的“石头”投掷,并将导致平局,为每个玩家投掷函数addDraw()。我发现了一个一维函数指针数组的例子,它可以工作

当我试图编译时,我的代码抛出了几个错误。如果还需要什么,请告诉我

函数调用结果:

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 }
    };
}
所有函数都在Player.h中初始化,并在Player.cpp中声明(我认为这是正确的术语)。我收到的最常见错误是“错误C2440:初始化”:无法从“void(\uu thiscall Player::*)(void)”转换为“void*”

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 } };

您有一个空指针数组,而不是函数指针,成员函数也不是函数指针

你需要像这样的东西

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::函数 .< /P> < P>在C++中,方法不是一个函数。如果你的计数器在一个类实例中,那么调用的代码需要知道<代码>这个<代码>。 要解决这个问题,有几种方法:

  • 不要使用
    void(*)(
    函数,而是使用
    void(*)(MyClass*)
    并将要更新的实例传递给函数

  • 使用指向成员的指针。这基本上是相同的,但语法有点奇怪;类型是
    void(MyClass::*)()
    ,要使用成员指针进行调用,语法将使用奇怪的
    ->*
    运算符,例如使用
    (This->*m[i][j])()

  • >p>使用C++。从语法的观点来看,这需要更干净一些;而不是使用指针的函数来使用矩阵的代码:>代码>:函数:< /Cord>对象,它捕获对象实例。C++闭包不能处理向上的FunARG问题,但在这种情况下,这不应该是问题。(在我看来,不需要让实例中的一个闭包保存计数器)

    但是,在非常特殊的情况下,我根本不会使用指向函数的指针,而是使用一个结果为(0,1,2)的整数矩阵,然后更新结果,代码只是

    results[m[i][j]]++;
    

    没有
    if
    s,也不涉及调用。在这个想法中,
    结果
    是一个由三个整数组成的数组,其计数器分别为A的wins、B的wins和ties。

    所有函数都在Player.h中声明,并在Player.cpp中定义。这是正确的。您声明了一个指向
    void
    的3x3指针数组,您可能的意思是
    void(播放器::*results1[3][3])();
    (假设函数不是静态的)。如果你真的想在不失去理智的情况下走这条路,你应该首先
    typedef
    成员函数指针类型。你还需要在使用指针时提供一个对象。谢谢你,闵富。尽管这仍然会引发:错误C2440:“初始化”:无法从“重载函数”转换为“无效(u cdecl*)(无效)“我希望我在使用C++方面足够成熟,知道如何使用STD:函数。在互联网上寻找解决相关问题的方法,这是一个最简单的方法。”
    results[m[i][j]]++;