Funktion einer Klasse übergeben
-
Ich möchte zur Laufzeit einem Objekt die Funktion einer Klasse zuordnen.
Habe ich es mit einer globalen Funktion zu tun, ist das einfach, ich übergebe einfach die Addresse der Funtion:long z_on = (long) sel_choice;
Und die Funktion sähe so aus:
void sel_choice()
{
...
}Will ich nun eine Klassenfunktion übergeben, ist das auch mit dem this-> Operator nicht möglich.
Wie mach ich's richtig?
-
Scope-Operator???
-
Um noch präziser zu sein. Ich habe die Klasse Foo, darin die Member Funktion sel_choice, die ich übergeben möchte:
class Foo
{
...
void sel_choice(long n);
};void (Foo::*ptsel) (long n);
Das kann ich ansprechen, wenn eine Instanz der Klasse gebildet wird:
ptsel = &Foo::sel_choice;
Denn wiederum will ich zu einem long casten, wie oben
long z_on = (long) sel_choiceaber da sagt der Compiler, das ist nicht zulässig (was durchaus logisch ist, da ein void zu einem long gecastet wird. Nebenbei: Wieso geht das mit der globalen Funktion?)
Aber die Haupftrage bleibt:
Wie kann ich die Methode der Klasse als Pointer übergeben?
-
Könntest du vllt. mal den gesamten relevanten Codeabschnitt posten? Aus diesen Fragmenten da wird man nicht schlau, wo jetzt welcher Gültigkeitsbereich liegt.
Dass
long z_on = (long) sel_choice
außerhalb der Klasse nicht funktioniert ist natürlich kein großes Wunder.Funktionspointer sehen an sich auch anders aus, natürlich kannst du sie auf long casten, trägt aber nicht unbedingt zur Codeübersicht und ggf. auch nicht zur Programmstabilität bei, wenn du dann aus Versehen mal einen Ptr. auf ne Funktion mit anderem Rückgabewert oder anderen Parametern übergibst.
class Foo { .. void SetFunct ( void (*funct)(void) ); void DoSomeStuff( void ); }; int main() { Foo bar; bar.SetFunct ( bar.DoSomeStuff ); ... }sollte doch funktionieren...
-
Herzlichen Dank, Hasu, aber wahrscheinlich hat sich da ein kleiner Rechtfehler eingeschlichen, jedenfalls bekomme ich folgende Antwort:
error C2664: 'Foo::SetFunct': Konvertierung des Parameters 1 von 'void' in 'void (__cdecl *)(void)' nicht möglichDer Code ist relativ trivial:
class Foo { ... void sel_choice(long n); }; void (Foo::*ptsel) (long n);Dann erzeuge ich irgendwo anders eine neue Instanz der Klasse:
void Irgendwo() { Foo* Neu = new Foo(); ptsel = &Foo::sel_choice; Neu->checkbutton_event = long(ptsel); }Der Cast auf long ist nicht meine Idee, dieser Datentyp wird erwartet und es muß eine void Funktion sein.
Bin zeimlich ratlos... :p
-
Percy2000 schrieb:
...
error C2664: 'Foo::SetFunct': Konvertierung des Parameters 1 von 'void' in 'void (__cdecl *)(void)' nicht möglichclass Foo { ... void sel_choice(long n); }; void (Foo::*ptsel) (long n);...
Der Cast auf long ist nicht meine Idee, dieser Datentyp wird erwartet und es muß eine void Funktion sein....Du versuchst (egal, ob das "Deine Idee" ist oder nicht), ein eckiges Schwein durch ein Rundes Loch zu pressen....Was nicht geht, geht nunmal nicht.
Was soll denn auch passieren, wenn eine Funktion, die einen long-Parameter verlangt, ohne Parameter aufgerufen werden soll ?
Mir würde höchstens einfallen, einen Wrapper zu schreiben - immerhin hast Du (wenn ich das recht sehe; (*)) sowieso das Problem, dass checkButton-Event keine Memberfunktion entgegennehmen kann, sondern nur eine "freie" Funktion...
da hilft auch nicht der Umweg über "ptsel":class Foo { ... void sel_choice(long n); void (*checkbutton_event)(void); }; void wrapper(void) { Foo f; f.sel_choice(1.23f); } void Irgendwo() { Foo* Neu = new Foo(); Neu->checkbutton_event = wrapper; }Ich verstehe das Konstrukt aber nicht wirklich ...
() Welchen Typ hat denn checkbutton_event ? Lt. Compiler void()(void) ...Gruß,
Simon2.
-
Tipp:
Mann kann ,wenn man ne meldung schreibt, unten auf den **C/C++*Button das erste mal klicken dahinter den cpp Code eingeben dann das zweite mal auf dan sich schon in C/C++ gäenderten Button das zweite mal clicken und damit wider normal schreiben. PS:
Wenn man schreibt verendert sich nichts sondern zeigt sich : [c++] und [/c++] an erst in der vorschau oder nachricht kann man ein meldungsfenster mit dem code sehen!Viel spaß: Maximilian
-
Herzlichen Dank zunächst für die geduldige Unterstützung.
Habe mich unterdessen durch die Probleme fon Member-Fuktionszeigern durchgearbeitet - und gesehen, dass da einiges wirklich arg ist.Das Problem, das ich habe, lässt sich auf eine eigentliche simple Fragestellung runterbrachen.Ich habe in der Klasse eine Funktion, die einen byte* Wert haben möchte - das ist ein Interface, auf das ich keinen Einfluss habe. Sonderbarer geht dies über den long-Wert, etwa so EVENT(long l);
Ich kann jetzt über den Funktionszeiger alle erdenklichen Funktionen der Klasse ansteuern, auch aus anderen Klassen, aber ich bekomme keine Möglichkeit, die Addresse der Funktion dieser spezifischen Instanz mitzuteilen - jedenfalls nicht über einen Cast, auch nicht über den Adress-Operator.
Vielleicht ist's wirklich so, dass da ein rundes Schwein durch ein eckiges Loch will...