2016-01-01 2 views
0

У меня есть большой код, и у меня есть ошибка в середине. Вот упрощенная версия частей кода с ошибкой.Ошибка вызова указателя на функцию-член в C++

И это ошибка я получаю:

// 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*/ 

выражения предшествующего скобку кажущегося вызова должно иметь (указатель-to) типа функции.

} 

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

Правильный синтаксис для вызова указатель функции метод (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); 
} 
2

Я советую использование станд :: функция вместо указателя функции. Синтаксис Std :: function более дружелюбен, любой тип функции может быть назначен ему из сырых функций в выражение lamdba. Мне также кажется немного странным, что вы передаете p1, p2, p3, p4, поскольку параметры функции даже там постоянны. Это будет труднее использовать. По крайней мере, вы можете переопределить() оператор. И вызовите параметры передачи с помощью оператора(), так как пользователю в этот момент времени не потребуется параметр pass в функции «timer».

Если вы должны использовать указатель на функцию Я думаю, что лучше:

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(); 

так, что клиент класса задач можно назвать задачу() непосредственно с легкостью.

ИМХО код будет лучше, как:

#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(); 
    } 
} 
+0

Ну я не знаю, о неприменении этих вещей! Вот почему я использовал указатель для работы! –

+0

Большое вам спасибо за ваш ответ! это было так полезно, поэтому я дал ему +1, но другой ответ был точным ответом на вопрос, поэтому я принял это! Но чтобы убедиться, что я был достаточно признателен, я пошел и дал много + 1s вашим недавним сообщениям :) Я пойду, узнаю, что функциональная библиотека! –

+0

Большое спасибо. Я рад, что вы нашли мой ответ полезным –