Problem mit static Memberfunktion
-
MasterG87 schrieb:
Class example { static const double bar() { foo(); return 1.; } void foo(){//Code} };SeppJ schrieb:
Es ist natürlich unmöglich von einer statischen Memberfunktion eine nicht-statische Memberfunktion aufzurufen. Das sollte offensichtlich sein.
Das wird wahrscheinlich das Problem sein, da es für mich nicht offensichtlich war. Wie kann ich das denn umgehen?
SeppJ schrieb:
Bei deinem Beispiel ist foo jedoch eine freie Funktion, was kein Problem darstellen würde. Andererseits ist dein Funktionsaufruf total falsch, so geht das nicht.
Wieso ist foo ein freie Funktion? Sie steht doch mit in der Klasse drin und müsste dadurch eine Klassenfunktion sein. Den Funktionsaufruf habe ich im obigen Code natürlich verbessert.
SeppJ schrieb:
Gibt mal wirklich 1:1 den Code der den Fehler verursacht, die Fehlermeldung und eine Beschreibung was du machen willst.
P.S.: Und const double als Rückgabewert?
Was soll das denn werden?Ich dachte ich schreibe mal einfachen Beispiel Code der meinen Fehler darstellt, deswegen auch das völlig willkürliche const double:-)
Ich versuche jetzt mal meinen Orginalcode gekürzt wiederzugeben://Die Methode find_min liegt in einer externen Bibliothek und hat folgenden Prototyp: template<typename funct_der> double find_min(const funct_der& der); bool Super::operator()(Particle_ &first, Particle_ &second) { //Code double tmp = find_min(&getDeriv); //Code return true; } // Diese Funktion ist im hpp-File static deklariert worden. const column_vector Super::getDeriv(const column_vector& alphaarg) { //Code gradF(alpha1,alpha2,gradF1,gradF2); //Memberfunktion der Klasse Super column_vector res; //Code return res; } void Super::gradF(Scalar& alpha1,Scalar& alpha2,Scalar& gradF1,Scalar& gradF2) { //Code gradF1 = 1; gradF2 = 1; }Da ich in einem großen Projekt arbeite bin ich an den obigen Aufbau ziemlich gebunden. Der obige Code wirft folgenden Fehler:
"error: cannot call member function 'void Super::gradF(Scalar&, Scalar&, Scalar&, Scalar&)' without object".
Wie kann ich das Ganze zum laufen bringen? Die Funktion getDeriv müsste in meinem Projekt nicht unbedingt static sein. Ich hab das nur gemacht um Compilerfehler zu vermeiden.
-
In einer statischen Funktion kann man nie nicht-statische Funktion aufrufen, weil eine statisch Funktion eine Klassenzugehörigkeit (du brauchst kein Objekt um darauf zuzugreifen) und eine statische Funktion eine Objektzugehörigkeit (Du brauchst stets ein Objekt umd darauf zuzugreifen) hat.
Zudem kannst du dir das "const" bei return-by-value (bei primitiven Typen) sparen weil hierbei das Zurückgegebene per Definition ein rvlaue ist.
-
Es ist ein großer Unterschied zwischen static und non-static. Eine Funktion in static ändern um Compilerfehler zu verhindern ist Käse...
nicht-statische Funktionen brauchen immer ein Objekt, auf dem sie aufgerufen werden. Statische Funktionen nimmst du dann, wenn die Funktion logisch zu der Klasse gehört, aber ohne Instanz einer solchen funktioniert. Das können dann Factories sein, oder Vereinfachungen bei Umwandlungen, usw.
Aber willkürlich eine Funktion als static umdeklarieren geht definitiv nicht - oder was würdest du sagen, wenn ein Lebensmittelhändler einfach sagt "Dumme Schweinegrippepanik, die Leute kaufen nur noch Rind und Pute - deklarier ich einfach mein Schwein als Pute, damit ich nicht so viel Gammelfleisch wegwerfen muss"...
-
/* Um dir mal den Unterschied zwischen Objekt- und Klassenzugehörigkeit näher zu bringen ;-) */ #include <iostream> using namespace std; class Foo { public: /* objektzugehörig: Jedes Objekt, das du von dieser Klasse erstellst, hat ihr eigenes Attribut 'i'. */ int i; /* klassenzugehörig: Statische Elemente (wie 'si') existieren genau 1x in einer Klasse. Sie sind unabhängig von Objekten, d.h. sie exisitern, auch wenn keine Objekt dieser Klasse erzeugt wird. */ static int si; /* 'si' kannst du in einem Konstruktor nicht benutzen, weil ein Konstruktor für Objekte da ist, er initialisiert Objekte einer Klasse. 'si' muss somit außerhalb der Klasse initialisiert werden. */ Foo() : i(7) {} // Initialisierungsliste, die das objektzugehörige Attribut 'i' initialisiert. }; /* Initialisierung des statischen Elements 'si'. */ int Foo::si = 7; int main() { Foo objekt1; Foo objekt2; cout << objekt1.i << endl; cout << objekt2.i << endl; cout << Foo::si << endl; /* Es spircht allerdings nichts dagegen, etwas Klassenzugehöriges mittels Objekt zu benutzen, allerdings macht man das i.A. nicht, deswegen bekommst du dabei normal auch eine Warnung vom Compiler. Andersrum geht es wie gesagt nicht, da man für etwas Objektzugehöriges stets ein Objekt benötigt. */ cout << objekt1.si; getchar(); return 0; }
-
MasterG87 schrieb:
//Die Methode find_min liegt in einer externen Bibliothek und hat folgenden Prototyp: template<typename funct_der> double find_min(const funct_der& der); bool Super::operator()(Particle_ &first, Particle_ &second) { //Code double tmp = find_min(&getDeriv); //Code return true; } // Diese Funktion ist im hpp-File nun nicht mehr static deklariert. const column_vector Super::getDeriv(const column_vector& alphaarg) { //Code gradF(alpha1,alpha2,gradF1,gradF2); //Memberfunktion der Klasse Super column_vector res; //Code return res; } void Super::gradF(Scalar& alpha1,Scalar& alpha2,Scalar& gradF1,Scalar& gradF2) { //Code gradF1 = 1; gradF2 = 1; }Da ich in einem großen Projekt arbeite bin ich an den obigen Aufbau ziemlich gebunden. Der obige Code wirft folgenden Fehler:
"error: cannot call member function 'void Super::gradF(Scalar&, Scalar&, Scalar&, Scalar&)' without object".
Wie kann ich das Ganze zum laufen bringen? Die Funktion getDeriv müsste in meinem Projekt nicht unbedingt static sein. Ich hab das nur gemacht um Compilerfehler zu vermeiden.Ok ich habe jetzt eingesehen, dass static in diesem Kontext nicht sinnvoll ist. Danke für die Erklärung des Konzepts.
Wenn ich bei meinem Code das static weglasse, ergibt sich folgender Fehler:
"error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&Super::getFunc'"
Wie kann ich meinen obigen Code nun zum laufen bringen?
-
Z.B. boost::bind. Ändert aber nichts an der Tatsache, dass du ein Objekt brauchst, wenn du eine nicht-statische Memberfunktion aufrufen willst.
-
Ich hab jetzt boost:bind gegoogelt, sehe aber nicht wie mir das bei meinem Problem
helfen soll. Kannst du es noch etwas genauer erklären?
Danke.
-
Hast du auch nach "boost::bind with member functions" o.Ä gesucht?
Hier ein Beispiel:#include <boost/bind.hpp> #include <boost/function.hpp> #include <iostream> template <typename Predicate> void start(Predicate p) { p(); } struct Runner { void run() { std::cout << "Running..." << std::endl; } }; int main() { Runner r; boost::function<void()> fun = boost::bind(&Runner::run, &r); start(fun); }Du gibst dann in Super::operator() statt einem eigens angelegten Objekt (obiges "r") wohl einfach "this" mit.
-
Hallo an alle,
das von Dweb gezeigte Beispiel finde ich sehr gut beschrieben,
man könnte das in die FAQ mitaufnehmen ...
-
Ich habe meine Problem jetzt wie folgt gelöst:
Ich übergebe boost::bind(&Super::getDeriv,this,_1)://Die Methode find_min liegt in einer externen Bibliothek und hat folgenden Prototyp: template<typename funct_der> double find_min(const funct_der& der); bool Super::operator()(Particle_ &first, Particle_ &second) { //Code double tmp = find_min(boost::bind(&Super::getDeriv,this,_1)); //Code return true; } // Diese Funktion ist im hpp-File nun nicht mehr static deklariert. const column_vector Super::getDeriv(const column_vector& alphaarg) { //Code gradF(alpha1,alpha2,gradF1,gradF2); //Memberfunktion der Klasse Super column_vector res; //Code return res; } void Super::gradF(Scalar& alpha1,Scalar& alpha2,Scalar& gradF1,Scalar& gradF2) { //Code gradF1 = 1; gradF2 = 1; }