An der Verwendung von Funktionszeigern ist nichts auszusetzen. Zeiger auf nicht statische Elementfunktionen sind jedoch nicht wie normale Funktionszeiger: Elementfunktionen müssen für ein Objekt aufgerufen werden, das als implizites Argument an die Funktion übergeben wird. Die Signatur Ihrer Mitgliedsfunktion oben ist also
void (aClass::*)(int, int)
anstatt des Typs, den Sie verwenden möchten
void (*)(int, int)
Ein Ansatz könnte darin bestehen, das Element funktionsfähig zu machen. static
In diesem Fall muss kein Objekt aufgerufen werden, und Sie können es mit dem Typ verwenden void (*)(int, int)
.
Wenn Sie irgendeine nicht-statische Member der Klasse zugreifen müssen und müssen Sie mit Funktionszeiger halten, zum Beispiel , weil die Funktion Teil einer C - Schnittstelle ist, die beste Wahl ist, immer ein Pass void*
an Ihre Funktion Funktionszeiger und Anruf unter Ihr Mitglied über eine Weiterleitungsfunktion, die ein Objekt von der erhält void*
und dann die Mitgliedsfunktion aufruft.
In einer richtigen C ++ - Schnittstelle möchten Sie vielleicht sehen, wie Ihre Funktion ein Vorlagenargument für Funktionsobjekte verwendet, um beliebige Klassentypen zu verwenden. Wenn die Verwendung einer Vorlagenschnittstelle unerwünscht ist, sollten Sie Folgendes verwenden std::function<void(int, int)>
: Sie können für diese ein geeignet aufrufbares Funktionsobjekt erstellen, z std::bind()
.
Die typsicheren Ansätze, bei denen ein Vorlagenargument für den Klassentyp oder ein geeignetes verwendet wird, std::function<...>
sind der Verwendung einer void*
Schnittstelle vorzuziehen, da sie das Fehlerpotential aufgrund einer Umwandlung in den falschen Typ beseitigen.
Hier ein Beispiel, um zu verdeutlichen, wie ein Funktionszeiger zum Aufrufen einer Elementfunktion verwendet wird:
// 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);
}