Redefinition virtueller Methode mit anderer Signatur oder anderem Ergebnistyp in abgeleiteter Klasse
-
Also in der abgeleiteten Klasse bleibt die Methode nur virtuell, wenn Signatur und Rückgabetyp gleich sind?
Weiters darf sich der Rückgabetyp nur unterscheiden, wenn es die Signatur auch tut?
Weil im Buch steht, die Methode kann mit anderer Signatur ODER Rückgabetyp redefiniert werden... Dass sie dann nicht mehr virtuell ist, ist klar, aber von einem Compilerfehler ist nicht die Rede.
Und im letzten Absatz stimmt auch nicht, dass für das Objekt der abgeleiteten Klasse nur die nicht virtuelle Methode aufrufbar ist (Sondern bei einem Aufruf mit einem Basisklassenzeiger?!).
MfG
-
ceplusplus@loggedoff schrieb:
Also in der abgeleiteten Klasse bleibt die Methode nur virtuell, wenn Signatur und Rückgabetyp gleich sind?
Die Methode bleibt in jedem Fall virtuell - die unpassende Methode der abgeleiteten Klasse überdeckt allerdings die virtuelle Methode (und ist im Ernstfall nicht virtuell)
Weiters darf sich der Rückgabetyp nur unterscheiden, wenn es die Signatur auch tut?
Ja - das ist wie bei überladenen Funktionen

(OK, es gibt noch die Möglichkeit, den Rückgabetyp "kovariant" zu ändern, aber das ist eine andere Geschichte)Weil im Buch steht, die Methode kann mit anderer Signatur ODER Rückgabetyp redefiniert werden... Dass sie dann nicht mehr virtuell ist, ist klar, aber von einem Compilerfehler ist nicht die Rede.
Da ist dein Buch vermutlich etwas ungenau - oder du hast nicht richtig zwischen den Zeilen gelesen.
Und im letzten Absatz stimmt auch nicht, dass für das Objekt der abgeleiteten Klasse nur die nicht virtuelle Methode aufrufbar ist (Sondern bei einem Aufruf mit einem Basisklassenzeiger?!).
Welche Methoden verfügbar sind, hängt vom statischen Typ ab (darum wird bei meinem obigen Beispiel auch die int-Methode verwendet), welche Methode tatsächlich genutzt wird, vom dynamischen Typ und ihrer "Virtualität" (im Beispiel ist base::func(int) virtuell, wurde aber von dereived NICHT redefiniert).
-
Hi ceplusplus@loggedoff,
ich denke, Du hast die Fehlermeldung missverstanden: Der Compiler will Dir mitteilen, dass er vermutet, dass Du einen Fehler gemacht hast.
Aller Wahrscheinlichkeit nach handelt es sich hier auch nur um eine Warnung, die nicht zum Abbruch des Compiles führt ...Wie CStoll schon sagte: Du hast mit dem falschen Beispiel angefangen (weil Du nicht wusstest, das der Returnvalue nicht zur Signatur gehört)... und bist deswegen auf ein anderes Thema gekommen.
Fang doch nochmal von Vorne an mit:
struct Base { virtual void func() { std::cout << "Base func" << std::endl; } }; struct Derived : Base { void func(int i) { std::cout << "Derived func " << i << std::endl; } };Wenn Du damit Erfahrungen zum Thema "overwriting vs. overloading" gemacht hast, kannst Du mit "overloading mit unterschiedlichen Returnvalues" experimentieren.... z.B. mit
void f(); int f(); void f(int);Gruß,
Simon2.
-
ceplusplus@loggedoff schrieb:
Also in der abgeleiteten Klasse bleibt die Methode nur virtuell, wenn Signatur und Rückgabetyp gleich sind?
die signatur muss dieselbe sein, sonst wäre es nicht dieselbe funktion. der rückgabetyp muss der gleiche oder ein kovarianter sein. (wenn die basisklasse einen zeiger auf X zurückgibt, darf die funktion in der abgeleiteten klasse einen zeiger auf Y zurückgeben, falls Y von X abgeleitet ist)
Weiters darf sich der Rückgabetyp nur unterscheiden, wenn es die Signatur auch tut?
wenn sich die signatur unterscheidet, hast du eine andere funktion. deren rückgabetyp ist natürlich unabhängig von dem anderer funktionen.
lesetipp aus humesikkins C++ faq: überladen, überdecken, überschreiben
problematisch ist dabei vor allem, wenn du in der basisklasse mehrere funktionen überlädst und in der abgeleiteten klasse nur eine neu definierst, dann werden dort die anderen nämlich verdeckt.
-
Simon2 schrieb:
... "overwriting vs. overloading" ...
overriding
außerdem geht es dem OP mehr um "function hiding"
-
Danke an alle.
Nun scheint mir alles verständlich.MfG
-
queer_boy schrieb:
Simon2 schrieb:
... "overwriting vs. overloading" ...
overriding
außerdem geht es dem OP mehr um "function hiding"

Ach ja, der Klassiker
English ("overriding") -> Deutsch ("überschreiben") -> Englisch("overwriting") .. passiert mir immer wieder.
Hier war mir auch nicht ganz klar, ob er "-hiding" oder "-riding" ausprobieren wollte (spielt ja beides mit rein), weswegen mir das "-writing" unreflektiert passend vorkam.Sorry .... und danke für die Korrektur,
Simon2.
-
Ach, eins würd ich noch gern wissen:
Warum "Never redefine an inherited nonvirtual function" ?
MfG
-
ceplusplus@loggedoff schrieb:
Warum "Never redefine an inherited nonvirtual function" ?
Weil es da vom statischen Typ der verwendeten Variablen abhängt, welche Version der Methode letzlich aufgerufen wird:
class base { public: void func1() { cout<<"base::func1()"<<endl; } virtual void func2() { cout<<"base::func2()"<<endl; } }; class derived : public base { public: void func1() { cout<<"derived::func1()"<<endl; } void func2()//implizit virtual { cout<<"derived::func2()"<<endl; } }; int main() { derived obj; base& ref = obj;//Polymorphie funktioniert auch ohne Zeiger :D obj.func1(); obj.func2(); ref.func1(); ref.func2(); }
-
ceplusplus@loggedoff schrieb:
...Warum "Never redefine an inherited nonvirtual function"...
Weil abgeleitete Klassen häufig über Zeiger auf die Basisklasse verwaltet werden, und du mit Sicherheit nicht ein unterschiedliches Verhalten willst, je nach dem ob auf das Element direkt oder ob indirekt über den Zeiger der Basisklasse zugegriffen wird.
cu André
-
Mhm ok aber "Never ..." find ich etwas übertrieben.
MfG
-
ceplusplus@loggedoff schrieb:
Mhm ok aber "Never ..." find ich etwas übertrieben.
Es hei-t ja auch "Never change a running system"

oder anders ausgedrückt: es ist keine gute Idee, eine nicht-virtuelle Methode zu überschreiben - C++ verbietet es aber nicht.Und Ratschläge der Form "Never do xyz" solltest du nicht als "mach das auf gar keinen Fall, oder du schmorst in der Hölle" interpretieren, sondern als "bevor du das machst, überleg dir genau, was dabei rauskommt - und welche Alternativen du hättest".