Fehlermeldung bei Nutzung einer Klassenmethode in klassenzugehöriges struct
-
Sehr geehrte Community,
wie schon in der Überschrift zu sehen geht es um folgendes Problem.
Ich habe eine Klasse und dort sind ein paar Methoden deklariert und ein struct
class : someclass { ... struct example { someType *data; someType *temp; void someClass::(*fun1)(int, int* ); void someClass::(*fun2)(int*, Type1*, Type1*); } *s1, *s2; ... void firstFun(int val1, int *val2) { ... } void secondFun(int* val2, Type1* param1, Type1* param2) { ... } }Ich versuche nun dem Struct die beiden Funktionen zuzuweisen mittels
s1->data = somedata; s1->temp = sometemp; s1->fun1 = someClass::firstFun; s1->fun2 = someClass::secondFun;Ich erhalte dabei folgende Fehlermeldung:
void (someClass::)(int, int*)' does not match 'void (*)(int, int*)Das Ganze scheint mir etwas zu kompliziert, als das ich drauf kommen könnte. Hab schon einige unterschiedliche Konstellationen ausprobiert. Aber bisher kam immer irgendwie eine Fehlermeldung.
Hat jemand eine Idee?Mfg Inge
-
s1->fun1 = someClass::firstFun; s1->fun2 = someClass::secondFun;-> Hier muss ein & vor
s1->fun1 = &someClass::firstFun; s1->fun2 = &someClass::secondFun;Gruß,
XSpille
-
Danke XSpille,
nun kommt die Meldung, mit der auch Verständnisende ist.
(someClass::*)(int, int*)' to 'void (*)(int, int*)someClass::*) ist ja eigentlich auch als void deklariert. Hier scheint es so, als müssten Klassenmethoden separat irgendwo deklariert werden. Weiß jemand wie und wo?
Grüße und danke nochmal!
-
Ingeborg schrieb:
class : someclass { ... struct example { someType *data; someType *temp; void someClass::(*fun1)(int, int* ); void someClass::(*fun2)(int*, Type1*, Type1*); } *s1, *s2;Soll das nicht vielleicht
void (someClass::* fun1)(int, int*);heißen?
Stichworte sind Methodenzeiger bzw. Memberzeiger (Pointer to member). Der Code ist nicht von dir, oder?
-
#include <iostream> using namespace std; class someclass { public: someclass() { s1 = new example; s1->data = "test1"; s1->temp = "test2"; s1->fun1 = &someclass::firstFun; } ~someclass(); struct example { const char *data; const char *temp; void (someclass::*fun1)(const char* , const char* ); } *s1; static void staticFun(void* param) { example* ex = (example*)param; ex->*fun1( ex->data, ex->temp); } void firstFun(const char* val1, const char* val2) { cout << val1 << " " << val2 << endl; } } ; int main() { someclass* cl = new someclass; cl->staticFun((void*)cl->s1); }Nein, ich habe den Code selber geschrieben. Ich habe ihn mal auf dieses Beispiel runtergebrochen und folgende Fehlermeldung erhalten.
error: 'fun1' was not declared in this scopeDiese Meldung ist eigentlich das letzte Problem. Ich lerne Programmieren nach dem Learning by Doing Prinzip und habe meine Erfahrungen aus Tutorials, welche ich mal mehr oder weniger komplett verstanden habe. Da kommt schonmal Halbwissen bei rum. Die Funtion s1->fun1 wurde schon im Konstruktor deklariert. Daher verstehe ich den Ärger nicht ganz. Ich danke aber für die Hilfe. Mache ich beim casten Mist? Hab irgendwo gelesen, dass diese Art zu casten warum auch immer nicht so ganz stilecht ist.
Mfg Inge
-
Ingeborg schrieb:
Nein, ich habe den Code selber geschrieben.
Memberzeiger sind halt schon ein ziemlich exotisches Feature, was man nicht unbedingt jeden Tag braucht und das man als Anfänger auch erstmal links liegen lassen kann. Du benutzt hier jetzt Memberzeiger, aber schreibst was von Problemen bei der "Nutzung einer Klassenmethode", als ob du dir gar nicht darüber bewusst bist, dass das Problem mit Memberzeigern zusammenhängt. Daher meine Vermutung.
error: 'fun1' was not declared in this scopeStimmt doch auch, oder nicht? Da wo du fun1 benutzt, gibt es keine Variable fun1. Da dein Code nicht vollständig ist, kann ich nur mutmaßen, was der Fehler ist, aber es könnte schon reichen, fun1 durch s1->fun1 zu ersetzen. Dann muss der Ausdruck m.W. aber auch anders geklammert werden:
(ex->*s1->fun1)(ex->data, ex->temp)Ich lerne Programmieren nach dem Learning by Doing Prinzip und habe meine Erfahrungen aus Tutorials, welche ich mal mehr oder weniger komplett verstanden habe.
Das halte ich nicht für eine gute Idee, da du so keine guten Rückmeldungen kriegst, wenn du was falsch machst. Nur weil etwas durch den Compiler geht und "funktioniert", heißt das nicht, dass es richtig ist. Vieles was man machen kann, hat undefiniertes Verhalten, d.h. es kann sofort abstürzen, es kann später abstürzen, es kann völlig unbeteiligte Variablen beeinflussen, es kann auch zufällig funktionieren und Monate später zusammenbrechen. Deshalb muss man schon definitiv wissen, was man eigentlich tut, nicht nur rumprobieren. Bei den Tutorials hast du das gleiche Problem auf einer anderen Ebene. Die werden meistens von Anfängern geschrieben, die das aufschreiben, was sie bisher meinen verstanden zu haben. Da fehlt dir genauso die Rückmeldung, ob das jetzt alles so gut und richtig ist, was du da lernst. Besorg dir ein, zwei vernünftige Bücher, ohne geht es m.E. nicht.
-
Hallo Bashar,
Ich lese das jetzt erst. Deswegen schreibe ich auch jetzt erst.
Grundlegendes: Ich habe das Problem so gelöst, dass ich die Funktionalitäten auf die ich zugreifen möchte ausgelagert habe in eine andere Klasse. Ein Objekt wird davon gebaut und als nächstes weitergegeben an den Konstruktor primär wichtige Klasse übergeben. Über den Klassenpointer konnte ich dann auf die Methoden zugreifen, ohne Methodenpointer.
Ich gehe davon aus, dass das Problem mit der statischen Deklaration zu tun hat.
Es gibt halt folgendes Probem was ich vermute. Statische Klassenfunktionen lassen keine Übergabe des This Pointers zu, was ja auch logisch ist, da statische Methoden für Funktionen verwendet werden, die objektunabhängig mit dem :: Operator angewandt werden können. Dagegen spricht, das ich Variablenpointer recht gut übergegen konnte.Mit der Auslagerung der Funkionen in eine Funktionsklasse ließ sich das Problem nun umgehen.
Noch etwas:
Ich habe auch Buchliteratur durchstöbert und du hast recht. Klassenmethodenpointer sind eine sehr rar gesähte Anwendung, daher findet man sie selbst in diesen Büchern nicht oder nurselten. Bei den Tutorials gebe ich dir sehr recht. Diese Erfahrung habe ich auch gemacht, daher ist es sinnvoll den Hintergrund der Schreiber zu prüfen. Meist bin ich über die c++ Seite auf Tutorials gegangen und die waren recht gut.
Danke und Grüße!
Inge
-
Wenn du
std::functionundstd::bindverwendest, kannst du so ziemlich alles aufrufen: Freie Funktionen, statische und nicht-statische Memberfunktionen, Funktionsobjekte. Du musst nur eine Signatur festlegen...