Funktionsobjekte
-
Hallo,
ich möchte für die Suche nach Nullstellen einer bestimmten Funktion verschiedene Algorithmen (Bisection, Ridder's Method, Brent's Algorithm, usw) verwenden. Zu diesem Zweck will ich Funktionsobjekte in Verbindung mit dem Strategy-Pattern einsetzen, d.h. ich will das Kontext-Objekt mit einem bestimmten Algorithmus "konfigurieren".
Nun zu meiner Frage? Ist die Verwendung von Funktionsobjekten performant oder sollte ich lieber Funktionspointer verwenden? Wie würdet ihr die Sache angehen?
Hier mein Ansatz (auszugsweise):
// Spezielle Funktion, für welche die Nullstellen ermittelt // werden sollen. class Function { public: float operator()(float x); }; // Abstrakte Basisklasse fuer die Algorithmen. class RootFinding { protected: Function m_function; public: virtual float find(void) = 0; }; // Konkreter Algorithmus zur Nullstellensuche. class Bisection : public RootFinding { public: Bisection(float, float, float, Function); virtual float find(void); };Dann hätte ich da noch eine Frage: Natürlich würde ich gern in der abstrakten Basisklasse lieber eine Referenzvariable halten (Function& m_function). Dies setzt natürlich voraus, dass die Initialisierung per Initialisierungsliste vollzogen wird. Doch wie mache ich das dann in der abgeleiteten Klasse mit der Initialisierung der Referenzvariable der Basisklasse?
Vielen Dank für die Hilfe
Toru
-
Toru schrieb:
Nun zu meiner Frage? Ist die Verwendung von Funktionsobjekten performant oder sollte ich lieber Funktionspointer verwenden? Wie würdet ihr die Sache angehen?
Funktionsobjekte können theoretisch performanter sein, da der Compiler bessere Optimierungsmöglichkeiten hat (inline), langsamer sind sie sicher nicht.
Toru schrieb:
Dann hätte ich da noch eine Frage: Natürlich würde ich gern in der abstrakten Basisklasse lieber eine Referenzvariable halten (Function& m_function).
Warum?
Toru schrieb:
Dies setzt natürlich voraus, dass die Initialisierung per Initialisierungsliste vollzogen wird. Doch wie mache ich das dann in der abgeleiteten Klasse mit der Initialisierung der Referenzvariable der Basisklasse?
das ist kein Problem. Du übergibst das Funktionsobjekt im Konstruktor und reichst es an die Basisklasse durch. Also etwa so:
// Spezielle Funktion, für welche die Nullstellen ermittelt // werden sollen. class Function { public: float operator()(float x); // const ? }; // Abstrakte Basisklasse fuer die Algorithmen. class RootFinding { protected: RootFinding( Function& f ) : m_function( f ) {} Function& m_function; // const Function& ? public: virtual float find(void) = 0; }; // Konkreter Algorithmus zur Nullstellensuche. class Bisection : public RootFinding { public: Bisection( float, float, float, Function& f ) : RootFinding( f ) // <- hier Funktionsobjekt durchreichen // , weitere Member initialisieren {} virtual float find(void); };BTW.: was ist der Unterschied zwischen 'Ridder's Method' und 'Regula Falsi'?
Gruß
Werner
-
Werner Salomon schrieb:
Toru schrieb:
Dann hätte ich da noch eine Frage: Natürlich würde ich gern in der abstrakten Basisklasse lieber eine Referenzvariable halten (Function& m_function).
Warum?
Ich mag keine Kopien.

Werner Salomon schrieb:
BTW.: was ist der Unterschied zwischen 'Ridder's Method' und 'Regula Falsi'?
Sicher hilft das hier weiter: http://www.nrbook.com/b/bookcpdf/c9-2.pdf