Function-Pointer , und Class Method
-
Ein Member-Funktionszeiger benötigt immer ein Objekt (Instanz) als zusätzliches Argument, für das es aufgerufen wird. Wenn du die Klassenfunktion statisch (
static
) machst, dann kannst du sie mit einem normalen Funktionszeiger aufrufen (&Foo::ProgressCallFunc
), kannst jedoch innerhalb dieser Funktion nicht auf nicht-statische Member zugreifen.Wenn es eine reine C++-Lösung werden soll, dann nimm, wie erwähnt, std::function (s. Beispiel) oder eben als Template.
Wenn es auch von C aus aufrufbar sein soll, dann übergebe als zusätzlichen Parameter
void *
, welches du dann innerhalb der Funktion wieder in einen Klassenzeiger zurück casten mußt.
-
@SoIntMan sagte in Function-Pointer , und Class Method:
@Schlangenmensch ja sorry ich wollte auch die "ProgressCallFunc" Menber funktion zuweisen. und ich habe leider deinen Vorschlag nich verstanden
Vielleicht hilft das weiter:
https://stackoverflow.com/questions/6458612/c0x-proper-way-to-receive-a-lambda-as-parameter-by-referenceDer Aufruf von dem Template könnte z.B. dann so aussehen (ungetestet):
void DoFoo() { auto callBack = [this](int i) { ProgressCallFunc(i); }; DoBar(callBack); }
-
Kleiner Hinweis noch, ich verwende (muss) VS 2008 C++
-
@SoIntMan sagte in Function-Pointer , und Class Method:
Kleiner Hinweis noch, ich verwende (muss) VS 2008 C++
Das ist ja erst 11 Jahre alt. Seitdem hat sich auch in der IT fast gar nichts verändert. Nur 3 neue C++-Standards. Sorry, aber wenn du nicht einmal C++11 nutzen kannst, dann ist irgendwas falsch.
Ohne Lambdas? Dann mach dir ne eigene struct, speichere das this des Foo-Objektes darin und überlade
operator()
. Oder besser: beseitige den Grund, warum du noch VS 2008 nutzen musst.
-
@wob: so ist das nunmal , kann es nicht ändern..
Naja ich bekomme das nicht hin , auch mit dem std::function und std:bind nich... ich denke ich lasse das einfach
-
@SoIntMan std::function ist auch erst ab C++11 verfügbar.
Du kannst dir eine Hilfsklasse mit operator() erstellen:
class Bar { public: template <typename Fn> static void DoBar(Fn f) { for (int i = 0; i < 100; ++i) { // Do hard work f(i); } } }; class Foo { private: void ProgressCallFunc(int i); public: void DoFoo(); friend class FooLambda; }; class FooLambda { Foo *foo; public: explicit FooLambda(Foo *foo) : foo(foo) {} void operator()(int i) { foo->ProgressCallFunc(i); } }; void Foo::ProgressCallFunc(int i) { //Get Progress state } void Foo::DoFoo() { // Call (in Thread) Bar::DoBar(FooLambda(this)); }
Das FooLambda könnte man durch ein Lambda ersetzen - seit 2011. Du musst eben irgendwie dafür sorgen, dass das ProgressCallFunc weiß, auf welches
this
es angewendet werden soll.
-
Hier noch ein kleines old-school Beispiel mit Pointer to Member Function:
#include <iostream> class Foo; typedef void(Foo::*ProgressCallbackFunc)(int i); class Bar { public: static void DoBar(ProgressCallbackFunc funcptr, Foo& foo) { for (int i = 0; i <= 10; ++i) { (foo.*funcptr)(i*10); } } }; class Foo { private: void ProgressCallFunc(int i) { std::cout << "Progress: " << i << "%\n"; } public: void DoFoo() { Bar::DoBar(&Foo::ProgressCallFunc, *this); } }; int main() { Foo foo; foo.DoFoo(); }
-
Mahlzeit:
@wob : Danke für dein Beispiel:) Aber für meinen Nutzen wird das zu Komplex
@theta : Auch schönes Beispiel, aber ging das auch generisch?, so dass Foo irgend eine Klassen sein kann?
-
@SoIntMan sagte in Function-Pointer , und Class Method:
aber ging das auch generisch?
So?
template <typename MemFn, typename Instance> static void DoBar(MemFn funcptr, Instance& foo)
-
@SoIntMan, es gibt äquivalente Funktionalität in Boost (
boost::function<..>
undboost::bind(..)
). Falls du das benutzen kannst, wäre das sicher ein Vorteil.