Wie kann ich pass eine member-Funktion, in dem eine freie Funktion erwartet wird?
Die Frage ist die folgende: betrachten Sie diese Stück code:
#include <iostream>
class aClass
{
public:
void aTest(int a, int b)
{
printf("%d + %d = %d", a, b, a + b);
}
};
void function1(void (*function)(int, int))
{
function(1, 1);
}
void test(int a,int b)
{
printf("%d - %d = %d", a , b , a - b);
}
int main (int argc, const char* argv[])
{
aClass a();
function1(&test);
function1(&aClass::aTest); //<-- How should I point to a's aClass::test function?
return 0;
}
Wie kann ich die a
's aClass::test
als argument zu function1
? Bin ich fest dabei.
Ich würde gerne den Zugriff auf ein member der Klasse.
- Werfen Sie einen Blick auf diese Antwort stackoverflow.com/questions/2402579/... und auch dieses C++ - FAQ parashift.com/c++-faq/pointers-to-members.html
- Das ist absolut kein Duplikat ist (zumindest nicht von der Frage verknüpft ist). Diese Frage ist etwa, wie zu erklären, ein Mitglied, das einen Zeiger auf eine Funktion; dies ist etwa gewusst wie: übergeben Sie einen Zeiger auf eine nicht-statische member-Funktion als parameter.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es nichts falsch mit der Verwendung von Funktionszeigern. Jedoch, Zeiger auf nicht-statischen member-Funktionen sind nicht wie die normalen Funktionszeiger: member-Funktionen müssen aufgerufen werden, ein Objekt, das übergeben wird, als eine implizite argument an die Funktion. Die Unterzeichnung des member-Funktion oben ist, so
eher als der Typ, den Sie versuchen zu verwenden
Könnte ein Ansatz darin bestehen, machen die member-Funktion
static
in dem Fall ist es nicht erforderlich, dass jedes Objekt, um aufgerufen werden, und Sie können es verwenden, mit der Artvoid (*)(int, int)
.Wenn Sie brauchen, um Zugriff auf nicht-statische member der Klasse und müssen Sie halten mit Funktionszeigern, z.B., weil die Funktion ist Teil der C-Schnittstelle, die beste option, um immer den pass ein
void*
auf Ihre Funktion, die Funktion Zeiger und rufen Sie Ihr Mitglied über eine weiterleitende Funktion erhält ein Objekt aus dervoid*
und ruft dann die member-Funktion.In einem richtigen C++ - Schnittstelle möchten Sie vielleicht einen Blick zu haben an, dass Sie Ihre Funktion nutzen und vorgefertigte argument für die Funktion der Objekte, um beliebige Klasse Typen. Wenn Sie eine vorgefertigte Schnittstelle ist unerwünscht, Sie sollte so etwas wie
std::function<void(int, int)>
: erstellen Sie ein entsprechend callable function-Objekt für diese, z.B. mithilfestd::bind()
.Typ-sichere Ansätze mit einem template-argument für die Klasse, Typ oder einem geeigneten
std::function<...>
sind vorzuziehen, als mit einemvoid*
- Schnittstelle, wie Sie entfernen Sie das Potenzial für Fehler aufgrund eines cast auf den richtigen Typ.Geklärt werden, wie eine Funktion Zeiger auf Aufruf einer member-Funktion, hier ein Beispiel:
void*
, das heißt, Sie können sehr böse Fehler, da es nicht typisiert mehr geprüft.void*
Lösung C) schlägt mit "die beste option, um immer den pass ein void* auf Ihre Funktion" undstatic_cast<foo*>(context)->member(i0, i1);
ist dies die einzige Lösung und ist sicher, die ist nicht Wir alle kennen die Probleme, die durch die Arbeit rund um das Typ-system, und Ihre Antwort IMHO fördert diesen Missbrauch.template <typename Fun> void f(Fun fun /*...*/)
und in der Umsetzung vonf()
verwenden Sie diefun
Objekt mit einem geeigneten Hilfsprogramm (z.B.std::bind()
und rufen Sie die Funktion über den Helfer mit passenden Argumenten.@Pete Becker ' s Antwort ist gut, aber Sie können es auch tun, ohne die
class
Instanz als expliziter parameter zufunction1
in C++ 11:void function1(std::function<void(int, int)>)
richtig?void function1(std::function<void(int, int)> functionToCall)
und dannfunctionToCall(1,1);
. Ich habe versucht, zu Bearbeiten, zu beantworten, aber jemand abgelehnt, als es nicht Sinn macht für einige Grund. Wir werden sehen, ob es wird von Ihnen positiv bewertet werden, irgendwann.Einen Zeiger auf member-Funktion unterscheidet sich von einem Zeiger auf Funktion. Damit eine member-Funktion über einen Zeiger muss ein Zeiger auf (offensichtlich), und ein Objekt, um es anzuwenden. Also die entsprechende version von
function1
wäreund nennen es:
function
imvoid (aClass::*function)(int, int)
war ein Typ, denn es ist eine Art intypedef void (aClass::*function)(int, int)
.int X;
ein Objekt erstellt.Seit 2011, wenn Sie ändern, können
function1
, weiß also, wie diese:(live-demo)
Beachten Sie auch, dass ich Feste Ihre defekte Objekt-definition (
aClass a();
eine Funktion deklariert).Stellte ich eine ähnliche Frage ( C++, openframeworks übergeben void von anderen Klassen ), aber die Antwort, die ich fand, war klarer, so dass hier die Erklärung für Zukunft records:
es ist einfacher zu bedienen std::function-in:
und dann rufen wie:
oder noch einfacher:
dem erstellen Sie einen lambda-Ausdruck, ruft das Objekt die Erfassung von Referenz -
Können Sie zu stoppen, schlug Ihre Köpfe jetzt. Hier ist der wrapper für die Mitglied-Funktion zur Unterstützung bestehenden Funktionen nehmen in plain C Funktionen als Argumente.
thread_local
Richtlinie ist hier der Schlüssel.http://cpp.sh/9jhk3
Bitte kommentieren Sie irgendwelche Probleme mit diesem Ansatz.
Anderen Antworten ausfallen zu nennen bestehenden plain
C
Funktionen: http://cpp.sh/8exunC
Funktionen als Argumente.Machte ich die member-Funktion als statische und alles funktioniert: