Problem mit abgeleiteter Klasse und virtual Funktionen
-
Hallo, wie im Titel beschrieben habe ich folgendes Problem:
EIne Basisklasse OUTPUTFUNCTION
und eine davon abgeleitete Klasse FUNCTION_SIGMOID
beide Klassen sind in einer shared library (Linux).Wenn ich mit CPPUNIT die Klassen teste bekomme ich einen Fehler, der darauf deutet, dass die Funktionen der Basisklasse und nicht der Kindklasse ausgeführt werden. Der Debugger bestätigt dies.
Wahrscheinlich sehe ich vor lauter Bäumen mal wieder nicht den Wald.
Vielen Dank im vorraus,
XZclass OUTPUTFUNCTION { public: OUTPUTFUNCTION(); virtual ~OUTPUTFUNCTION(); virtual double calculate(double input); void setTreshold(double Treshold); string getName(); protected: virtual void init(); string name; double treshold; }; class FUNCTION_SIGMOID : public OUTPUTFUNCTION { public: double calculate(double input); protected: void init(); };und hier die Implementierung der Vaterklasse:
OUTPUTFUNCTION::OUTPUTFUNCTION() { this->init(); }; void OUTPUTFUNCTION::init() { treshold = 1.0; name = "default"; } OUTPUTFUNCTION::~OUTPUTFUNCTION() {}; string OUTPUTFUNCTION::getName() { return name; }; double OUTPUTFUNCTION::calculate(double input) { return (input>treshold)?1:0; }; void OUTPUTFUNCTION::setTreshold(double Treshold) { treshold = Treshold; };Und die der Kindklasse:
void FUNCTION_SIGMOID::init() { name = "sigmoid"; treshold = 1; }; double FUNCTION_SIGMOID::calculate(double input) { return 1/(1+exp(-1*input*treshold)); };Und noch mein CPPUNIT code:
OUTPUTFUNCTION *temp; temp = new FUNCTION_SIGMOID(); function->setTreshold(1); CPPUNIT_ASSERT_EQUAL((double)0,function->calculate(0.9)); //sollte einen Fehler ergeben CPPUNIT_ASSERT_EQUAL((double)1,function->calculate(1.1)); //sollte ebenfalls einen Fehler ergeben string name = "sigmoid"; CPPUNIT_ASSERT_EQUAL(name,function->getName()); //sollte funktionieren, aber gibt einen Fehler CPPUNIT_ASSERT_EQUAL((double)0,function->calculate(-0.1)); CPPUNIT_ASSERT_EQUAL((double)1,function->calculate(0.1));equality assertion failed
- Expected: sigmoid
- Actual : default
-
Zunächst kläre bitte ob die Verwendung von function, obwohl temp initialisiert wurde ein Tippfehler ist.
-
Nein, es war kein Tippfehler, das stand so in meinem Code.
Vielen Dank, dass Du mir den Wald gezeigt hast.ein kleines Problem bleibt noch:
der Name ist noch immer "default".
Heißt das, dass ich eine virtuelle Funktion nicht innerhalb des Konstruktors aufrufen kann/darf? also einen neuen Konstruktor für die Kindklasse schreiben muss/soll, der dann ebenfalls init() aufruft?Gruß und Vielen Dank fürs öffnen der Augen,
XZ
-
Du darfst auf keinen Fall bei der Konstruktion oder Destruktion virtuelle Elementfunktionen aufrufen.
Deine OUTPUTFUNCTION.init() wird niemals FUNCTION_SIGMOID.init() aufrufen wenn du sie im Konstruktor von OUTPUTFUNCTION aufrufst, der Grund dafür liegt auf der Hand, bevor die Klasse FUNCTION_SIGMOID initialisiert wird, wird zuerst OUTPUTFUNCTION initialisiert, daher ist OUTPUTFUNCTION zu diesem Zeitpunkt noch gar keine Abgeleitete Klasse bekannt und wird intern auch als OUTPUTFUNCTION behandelt. Du rufst also in diesem Fall nur OUTPUTFUNCTION.init() auf, ich denke das ist es nicht, was du mit dem virtual vor der Elementfunktion erreichen wolltest.:p
-
Das habe ich mir zwar auch schon gedacht, aber ich wollte es nicht wahr haben
