在C ++

时间:2016-01-01 08:33:11

标签: c++ pointers function-pointers pointer-to-member

我有一个很大的代码,我的中间有一个错误。以下是包含错误的代码部分的简化版本。

这是我得到的错误:

// Followings are declared in the header

struct Task {
public:
    _COORD p1;
    int p2;
    object p3;
    speed p4;
    bool(Game::*function)(_COORD, int, object, speed);
};


std::vector<Task> tasks;

// Followings are defined in the source

void Game::timer() {
    (some code here)
tasks[i].function(tasks[i].p1, tasks[i].p2, tasks[i].p3, tasks[i].p4);     /*error here*/
  明显调用的括号前面的

表达式必须具有   (指向)函数类型。

}

void Game::explode(bool(Game::*function)(_COORD, int, object, speed), _COORD p1, int p2, object p3, speed p4) {
    ExplodeTask task;
    task.function = function;
    task.p1 = p1;
    task.p2 = p2;
    task.p3 = p3;
    task.p4 = p4;
    tasks.push_back(task);
}

有谁知道如何修复它?

2 个答案:

答案 0 :(得分:4)

调用方法函数指针的正确语法是(objectPtr->*methodPtr)()(object.*methodPtr)()

void Game::timer() {
    int i = 0;
    ...
    (this->*tasks[i].function)(tasks[i].p1, tasks[i].p2, tasks[i].p3, tasks[i].p4);
}

答案 1 :(得分:2)

我的建议是使用std :: function而不是函数指针。 Std :: function语法更友好,可以从原始函数到lamdba表达式为其分配任何函数类型。你也把p1,p2,p3,p4作为函数参数传递,即使有常数也似乎有点奇怪。使用这种方式会更难。至少你可以覆盖()运算符。并且调用通过()运算符传递参数,这样用户就不需要在&#34;计时器&#34;中第二次传递参数。功能。

如果你必须使用函数指针我觉得更好:

struct Task {
public:
    int p1;
    int p2;
    int p3;
    int p4;
    bool operator()()
    {
        return (functionPtr)(p1,p2,p3,p4);
    }
    bool(*functionPtr)(int, int, int, int );
};

Task t { 1, 2 ,3 ,4, &Game::foo(int, int, int, int) };

Than client can make a easy call without passing parameters like. 
t();

使Task类的客户端可以轻松地直接调用task()。

恕我直言的代码会更好:

#include <vector>
#include <functional>

std::vector<std::function<bool(void)>> functionList;

void taskPusher( std::function<bool(int,int,int,int)> foo , int p1, int p2, int p3, int p4)
{

    std::function<bool()> explodeTask = [=]()
    {
        return foo(p1,p2,p3,p4);
    } ;

    functionList.push_back(explodeTask);
}

void explode()
{
    for ( auto& explodeFoo : functionList)
    {
        explodeFoo();
    }
}