function-pointer vs member-function-pointer
-
Meep Meep schrieb:
static A *ptmp=NULL; static void foo(int i) { if(ptmp) ptmp->foo(i); } int main() { A o(5); ptmp= &o; return 0; }er verwendet den zeiger ptmp als pseude singleton. dem kann er immer nur eine instanz der klasse zuweisen.
void foo(int) ist die callback-func. die ueberprueft ob der zeiger ptmp auf ein objekt zeigt und ruft dann eine meber-func auf.
solange es fuer teddybär ausreichend ist, mit nur einer instanz seiner klasse zu arbeiten, ist der loesungsansatz recht gut.
Meep Meep schrieb:
vielleicht sollte ich sagen 'nur eine instanz der klasse die mit OPT++ zum jeweiligen zeitpunkt zusammenarbeiten kann'.
Das ^^ ist der entscheidende Satz!
Er kann natürlich for jedem Aufruf der Funktion, die seine Funtktion als Callback verwendet, den Zeiger umsetzen.
-
Mal 'ne Erweiterung von Boris' Variante:
//interface typedef void (*fun)(int, double); //Funktion, die globalen FktPtr haben will void callFun(fun function) { function(42, 3.14159f); } class MyClass { public: //ruft callFun fuer dieses Objekt auf void callCFun() { //wenns threadsafe sein soll, hier synchronisieren! currentCallObj = this; callFun(&interfaceFun); } private: //die problematische, nichtstatische Funktion void evilMember(int i, double d) { std::cout << i << " " << d << '\n'; } static MyClass* currentCallObj; //Interface auf statische Funktion //ggf. extern "C"! static void interfaceFun(int i, double d) { currentCallObj->evilMember(i, d); } }; MyClass* MyClass::currentCallObj; int main() { MyClass a; a.callCFun(); }
-
Vielen vielen Dank für die schnellen Antworten. Ich werde all diese mal testen und dann sehen, ob das für mein Problem brauchbar ist. Bis denne ...
-
So nun habe ich mal ein paar Tests gemacht und muss leider feststellen, dass die Lösung scheinbar nicht anzuwenden ist. Mein Problem ist die externe lib OPT++, die Klasse welche ich verwenden will, hat nen Constructor vom Typ:
OPTPP::FDNLF1(int ndim, USERFCN0 f, INITFCN i)mit
typedef void (*INITFCN)(int, NEWMAT::ColumnVector&); typedef void (*USERFCN0)(int, const NEWMAT::ColumnVector&, real&, int&);Für die beiden Funktionspointer INITFCN und USERFCN0 will ich nun Funktionen aus meiner Klasse nehmen
class my_class { public: // die problematischen Funktionen, welche ich NICHT als static annehmen kann void init_fcn(int n, NEWMAT::ColumnVector& x); void fcn0(int n, const NEWMAT::ColumnVector& x, double& fx, int& result); public: my_class(){} virtual ~my_class(){} };D.h. ich würde am liebsten schreiben
int main () { int n = 2; // Create an object of OPT++ using my_class functions OPTPP::FDNLF1 nlp(n, &my_class::fcn0, &my_class::init_fcn); // oder alternativ my_class A; FDNLF1 nlp(n, &A.fcn0, &A.init_fcn); return 0; }dies geht jedoch nur, wenn ich die Funktionen init_fcn und fcn0 in my_class als static kennzeichne

leider sehe ich nicht, wie ich Eure Ratschläge hier umsetzen sollte ...
-
Wenn ich mir OPT++ so ansehe, frage ich mich, wo der Sinn darin liegt, dass Deine Funktion in einer Klasse liegt.
-
Ich habe mein ganzes Programm in C++ geschrieben und durchweg objekt-orientiert gearbeitet. Es gibt also eine Klasse, welche das komplette Management übernimmt und dazu gehören u.a. die Funktionen init_fcn und fcn0 - diese beschrieben nicht einfach eine Funktion, welche ausgewertet werden soll, sondern stoßen weitreichende Berechnungen an (komplette FEM Simulation z.B.) ...
D.h. die Funktionen init_fcn und fcn0 sind nicht einfach "handcoded", sondern stehen für einen Anruf einer anderen software (z.B. FEM Simulation). Ich denke, dass es daher unmöglich ist diese Funktionen nicht in einer Klasse zu kapseln.
-
teddybär schrieb:
Ich habe mein ganzes Programm in C++ geschrieben und durchweg objekt-orientiert gearbeitet. Es gibt also eine Klasse, welche das komplette Management übernimmt und dazu gehören u.a. die Funktionen init_fcn und fcn0 - diese beschrieben nicht einfach eine Funktion, welche ausgewertet werden soll, sondern stoßen weitreichende Berechnungen an (komplette FEM Simulation z.B.) ...
D.h. die Funktionen init_fcn und fcn0 sind nicht einfach "handcoded", sondern stehen für einen Anruf einer anderen software (z.B. FEM Simulation). Ich denke, dass es daher unmöglich ist diese Funktionen nicht in einer Klasse zu kapseln.Wieso? Die FEM Simulation kann doch ein lokales Objekt in Deiner CB-Funktion sein.
-
was meinst Du denn mit "CB-Funktion" ???
Vielleicht sollte ich meine Situation anders formulieren: ich habe mir eine software geschrieben, welche verschiedene Optimierungsalgorithmen bereitstellt. Diese möchte ich nun um ein OPT++ Interface erweitern, d.h. der grobe Ablauf des Programmes ist bereits fest und dazu gehört auch, dass das Interface zur Funktionsauswertung in einer eigenen Klasse liegt (diese Klasse ist selber eine Art wrapper für andere software).
-
teddybär schrieb:
was meinst Du denn mit "CB-Funktion" ???
Callback Funtion.
-
und wie soll ich die FEM-software initialisieren, wenn diese innerhalb einer "globalen" Funktion steckt? Ich muss in der main zuerst eine komplette Initialisierung der FEM-software durchführen (also eine spezielle Klasse daraus deklarieren) und kann erst dann eine spezielle member-Funktion dieser FEM-Klasse ansprechen, welche die Auswertung durchführt ...
Und OPT++ braucht nunmal einen pointer auf genau diese Funktion
-
Du könntest eine freie Funktion verwenden und der dann eine Instanz dieser Initialisierungsklasse übergeben (die für Übergabe dann binden) oder die Funktion nutzt eine globale Instanz dieser Klasse.
-
Beantworte doch mal die Frage, warum die Funktionen nicht statisch sein dürfen. Wobei die einzigen technisch gültigen Argumente hier "Zugriff auf Membervariablen" (seh ich keine) oder "Implementieren eines virtuellen Interface" (weiss ich nicht) sind. Alles andere wären Designfragen.
Kapseln kann man auch über namespaces oder statische Klassen (gibt es in C++ so nicht, aber das Pendant wäre eine Klasse mit nur statischen Funktionen).
-
@ Braunstein: Globale Instanzen einer Klasse möchte ich nicht verwenden, da mir dies nicht sehr C++ like erscheint. Was meinst Du mit "freier Funktion" ?
@ LordJaxom: Warum ich die Funktionen nicht statisch machen kann, liegt darin dass dann ja auch alle Funktionen (auch in anderen Klassen) welche von dieser statischen Funktion aufgerufen werden selber statisch sein müssten - dies würde in letzter Instanz wohl dazu führen, dass ich meine ganze FEM-software als statisch deklarieren müsste. Schließlich bedeutet ja der Aufruf dieser Funktion (welche OPT++ haben will) bei mir soviel wie: mache eine komplette FEM Simulation !
-
Warum ich die Funktionen nicht statisch machen kann, liegt darin dass dann ja auch alle Funktionen (auch in anderen Klassen) welche von dieser statischen Funktion aufgerufen werden selber statisch sein müssten
Nein. Es müssen lediglich alle Elemente, auf du zugreifst statisch sein, ausser du übergibst die natürlich an die Funktion (von einem Interface mal abgesehen). Der aufrufende muss nicht statisch sein, um eine statische Funktion aufrufen zu können.
-
@ drakon: nur zum Verständnis: wenn ich in Klasse A eine statische Funktion habe und in dieser dann eine Funktion aus Klasse B aufrufen will, muss dann die Funktion in Klasse B statisch sein? Und was ist, wenn die Funktion in Klasse B nach dem Aufruf eigene Member (aus Klasse
ändern will? Was muss dann alles statisch sein?Kann der folgende Code so richtig sein?
class A{ private: B* Bpt; ... public: static void do_sth() { Bpt->do_sth(); } ... } class B{ private: double foo; // muss dieser member static sein ??? public: void do_sth() { foo = 42.; } // muss dieser member static sein ??? }
-
Nein. Das geht so nicht.
B* Bpt;Müsste statisch sein. Aber B selber muss keine statischen Member haben, da das Objekt ja bestimmt ist.
Du könntest das Objekt ja übergeben, dann muss Bpt nicht statisch sein.
Habe jetzt nicht den ganzen Thread gelesen, weiss darum nicht, was du genau brauchst.
Ev kannst du dir ja überlegen, ob du überhaupt mehrere Instanzen von A brauchst/erlaubst.