Não há nada de errado em usar ponteiros de função. No entanto, ponteiros para funções-membro não estáticas não são como ponteiros de funções normais: as funções-membro precisam ser chamadas em um objeto que é passado como um argumento implícito para a função. A assinatura da sua função de membro acima é, portanto,
void (aClass::*)(int, int)
em vez do tipo que você tenta usar
void (*)(int, int)
Uma abordagem poderia consistir em fazer o membro funcionar static
em cujo caso ele não requer qualquer objeto a ser chamado e você pode usá-lo com o tipo void (*)(int, int)
.
Se você precisar acessar qualquer membro não estático da sua classe e precisar void*
usar ponteiros de função, por exemplo, porque a função faz parte de uma interface C, sua melhor opção é sempre passar um para sua função, recebendo os ponteiros de função e chamando seu membro através de uma função de encaminhamento que obtém um objeto dovoid*
e depois chama a função de membro.
Em uma interface C ++ adequada, você pode querer que sua função use argumentos modelados para que objetos de função usem tipos de classe arbitrários. Se o uso de uma interface de modelo é indesejável, você deve usar algo como std::function<void(int, int)>
: você pode criar um objeto de função que possa ser chamado por eles, por exemplo, usandostd::bind()
.
As abordagens de segurança de tipo usando um argumento de modelo para o tipo de classe ou um adequado std::function<...>
são preferíveis a usar umvoid*
interface, pois elas removem o potencial de erros devido a uma conversão para o tipo errado.
Para esclarecer como usar um ponteiro de função para chamar uma função de membro, aqui está um exemplo:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, 0);
foo object;
somefunction(&forwarder, &object);
}