Deklaration von virtualen Funktionen
-
Hallo,
Der folgende Code verhaltet sich nicht so wie erwartet:
#include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; class A1 { public: virtual void test() { cout << "A1" << endl; } }; class B1 : public A1 { public: virtual void test() { test(1); } virtual void test(int value) { cout << "B1 " << value << endl; } }; class B2 : public A1 { public: virtual void test(int value = 1) { cout << "B2 " << value << endl; } }; int main(void) { A1 *test = new B1(); test->test(); // Output B1 1 delete test; test = new B2(); test->test(); // Output A1 delete test; return EXIT_SUCCESS; }Als Ausgabe bekomme ich:
B1 1
A1statt wie erwartet:
B1 1
B2 1Als Kompiler verwende ich g++ (GCC) 4.2.4.
Leider bin ich in c++ nicht so erfahren und bitte daher um hilfe.
-
#include <stdio.h> // brauchst du nicht #include <stdlib.h> // die auch nicht #include <iostream> using namespace std; class A1 { public: virtual void test() { cout << "A1" << endl; } }; class B1 : public A1 { public: virtual void test() { test(1); } virtual void test(int value) { cout << "B1 " << value << endl; } }; class B2 : public A1 { public: virtual void test(int value = 1) { cout << "B2 " << value << endl; } }; int main(void) { A1 *test = new B1(); test->test(); // Output B1 1 delete test; test = new B2(); test->test(); // Output A1 delete test; return EXIT_SUCCESS; }Du vererbst B2 A1, B2 sieht also nachher so aus:
class B2 : public A1 { public: virtual void test(int value = 1) { cout << "B2 " << value << endl; } virtual void test() { cout << "A1" << endl; } };Dann rufst du die test() Methode ohne Parameter auf -> A1 wird ausgegeben.
Probiers mal damit:
int main(void) { A1 *test = new B1(); test->test(); // Output B1 1 delete test; test = new B2(); test->test(5); // Output A1 => Output sollte B2 5 sein delete test; return EXIT_SUCCESS; }
-
Hallo,
Leider ist es mir immer noch nicht klar, da sich die funktion test2 so verhält wie ich es mir auch von der funktion test erwarten würde:
class B2 : public A1 { public: virtual void test(int value = 1) { cout << "B2 " << value << endl; } virtual void test2(int value = 5) { cout << "B2 test2 " << value << endl; }; }; int main(void) { A1 *test = new B1(); test->test(); // Output B1 1 delete test; test = new B2(); test->test(); // Output A1 B2* test1 = dynamic_cast<B2*>(test); test1->test2(); // B2 test2 5 test1->test2(10); // B2 test2 10 delete test; return EXIT_SUCCESS; }Warum wird die deklaration
virtual void test(int value = 1) { cout << "B2 " << value << endl; }nicht in
virtual void test() { test(1); } virtual void test(int value) { cout << "B1 " << value << endl; }umgeschrieben?
-
Was meinst du genau mit "umgeschrieben"? Wenn eine Funktion Standardparameter besitzt, dann werden bei einem Weglassen der Argumente die dort angegebenen Werte eingesetzt. Die Funktion bleibt die Gleiche.
Und benutze bitte [cpp]-Tags anstatt [code]-Tags, dann ist dein Code nämlich viel lesbarer.
-
Chri schrieb:
Warum wird die deklaration
virtual void test(int value = 1) { cout << "B2 " << value << endl; }nicht in
virtual void test() { test(1); } virtual void test(int value) { cout << "B1 " << value << endl; }umgeschrieben?
Weil das in C++ eben einfach nicht so ist!?!
Default-Parameter sind genau das: Default-Parameter.Die führen aber *nicht* dazu dass mehr als nur eine Funktion angelegt wird!
Default-Parameter kannst du dir so vorstellen, dass der Compiler überall wo die Funktion aufgerufen wird, den entsprechenden Wert einsetzt. Nicht mehr und nicht weniger.Klar jetzt?
-
danke für die hilfe
-
Ich weiß nicht, ob das klar geworden ist und ich hoffe jetzt nicht auch noch zur Verwirrung beizutragen.

Aber, obwohl eine Funktion wie z.B.
void f(int=0) { //... }ohne Parameter aufgerufen werden kann
f()deklarieren die Beiden Prototypen
void f() void f(int=0)völlig unterschiedliche Funktionen.
D.h. in deinem ersten Codebeispiel
class A1 { public: virtual void test() { cout << "A1" << endl; } }; //.. class B2 : public A1 { public: virtual void test(int value = 1) { cout << "B2 " << value << endl; } };überschreibt B2::test(int) NICHT die Funktion A1::test(void) der Basisklasse auch wenn B2::test(int) durch das Standardargument ohne Übergabe eines Wertes aufgerufen werden kann.
B2* pB2 = new B2(); pB2->test(); // funktioniert zwar, dennoch bleibt die Funktion vom // Typ void test(int) und überschreibt nicht die // Basisklassenfunktion, die ja vom Typ void test(void)istDas kannst du dir ganz leicht klar machen wenn du die Funktion der Basisklasse als rein virtuelle Funktion deklarierst. Dann scheitert nämliche das Folgende:
class A1 { public: virtual void test() = 0; // rein virtuell }; //... A1 *test = new B1(); test->test(); // Output B1 1 delete test; test = new B2(); // Fehler!!! test->test(); // Fehler!!!Hoffe nicht weiter vewirrt zu haben.
