VErerbung von rein virtueller Basisklasse
-
Hallo,
habe eine Frage:
ich habe eine rein virtuelle Basisklasse A. Diese Klasse A besitzt eine (rein virt.) Funktion mit Rückgabewert Zeiger auf A: A*. (zB virtual A* getPtr(); )
Bei der abgeleiteten Klasse B:A müßte also demnach der Rückgabewert B* sein.
Die implementierung in B habe ich dann so gemacht:A* B::B getPtr(){
...
return (etwas vom Typ *B);
}Der Compiler will aber jetzt verständlicherweise einen Rückgabewert vom Typ *A haben und meldet mir den Fehler, daß er *B nicht in *A konvertieren kann.
Weiß jemand wie die Implementierung aussehen muß? An der Basisklasse soll nichts mehr verändert werden.
Danke und Gruß Micha
-
Micha_1 schrieb:
ich habe eine rein virtuelle Basisklasse A
Eine abstrakte Basisklasse. Aber OK, ich weiß was du meinst
. Diese Klasse A besitzt eine (rein virt.) Funktion mit Rückgabewert Zeiger auf A: A*. (zB virtual A* getPtr(); )
Bei der abgeleiteten Klasse B:A müßte also demnach der Rückgabewert B* sein.Wieso "also demnach", ich finde das nicht zwingend. Aber OK, das ist kein Problem. Es gibt in C++ sog. "kovariante Rückgabetypen". In einer spezialisierten Implementation einer Methode kann auch der Rückgabetyp spezialisiert werden:
class Base { virtual Base* foo() = 0; }; class Derived : public Base { Derived* foo(); };
Hier geben die Methoden zufällig Zeiger auf ihre eigenen Klassen zurück, das ist aber kein Muss. Es könnte auch BaseX* und DerivedX* zurückgegeben werden.
Edit: Vererbung vergessen gehabt, hat aber keiner gemerkt
-
Bashar schrieb:
Micha_1 schrieb:
ich habe eine rein virtuelle Basisklasse A
Eine abstrakte Basisklasse. Aber OK, ich weiß was du meinst
<klugscheiß>IMHO ist eine Klasse schon abstrakt, wenn nur eine Methode nicht definiert ist. "Rein virtuell" heißt für mich aber, dass keine einzige Methode definiert ist, also fast sowas wie ein Interface.</klugscheiß>
Vielleicht könnte man "rein abstrakt" sagen?
-
Optimizer schrieb:
<klugscheiß>IMHO ist eine Klasse schon abstrakt, wenn nur eine Methode nicht definiert ist. "Rein virtuell" heißt für mich aber, dass keine einzige Methode definiert ist, also fast sowas wie ein Interface.</klugscheiß>
Abstrakter als abstrakt geht aber nicht
entweder abstrakt (d.h. sie enthält mindestens 1 rein virtuelle Methode -- mit definiert oder nicht hat das BTW gar nichts zu tun) oder nicht.
-
rein virtuell als bezeichnung für klassen, die keine virtuellen methoden selbst implementieren ist in C++ irreführend, denn leicht mit virtuellen basisklassen zu verwechseln (auch wenn letztere häufig auch ersteres sind).
-
Hallo und danke zunächst mal fürs Antworten.
Ja stimmt, es ist eine abstrakte Basisklasse. Tatsächlich soll sie rein virtuell sein, also nur ein Interface darstellen.
Ich war auch überzeugt, daß ein Zeiger auf eine abgeleitete KLasse auch vom Typ Zeiger auf Basisklasse sein darf, womit ich mit folgendem übereinstimme:
class Base { virtual Base* foo() = 0; }; class Derived { Derived* foo(); };
Mein Compiler macht das aber nicht (Borland). (Fehlermeldung: Virtual function 'B::getPtr()' conflicts with base class 'A')
Tatsächlich habe ich als Rückgabetyp vector<A*> in A geschrieben. (und müßte doch dann vector<B*> in B schreiben dürfen, oder?).
Ich hielt das aber nicht für das Kernproblem, aber vielleicht ist es das doch...mfg Micha
PS: @Bashar: Du hast in der Klasse Derived "virtual" nicht nochmal wiederholt. Erlaubt ist dies aber doch? (der Übersicht halber)
-
Micha_1 schrieb:
Tatsächlich habe ich als Rückgabetyp vector<A*> in A geschrieben. (und müßte doch dann vector<B*> in B schreiben dürfen, oder?).
Nein. Zwar sind A und B verwandte Type und damit auch A* und B* (nicht aber A** und B**). vector<A> und vector<B> sowie vector<A*> und vector<B*> stehen aber in keinerlei Beziehung zueinander (sie sind jeweils zwei unterschiedliche Instanziierungen der Template-Klasse std::vector) und sind damit auch nicht austauchbar.
PS: @Bashar: Du hast in der Klasse Derived "virtual" nicht nochmal wiederholt. Erlaubt ist dies aber doch? (der Übersicht halber)
Erlaubt ist es. Ob es übersichtlicher ist sei dahingestellt.
-
aha, also liegt hier doch das Problem.
Wie kann man denn eine Implementierung der Funktion in B dann realisieren? Die virtuelle Funktion samt Rückgabetyp in A war eine Vorgabe und sollte nicht verändert werden.
Danke nochmals..mfg Micha
-
Micha_1 schrieb:
aha, also liegt hier doch das Problem.
Wie kann man denn eine Implementierung der Funktion in B dann realisieren? Die virtuelle Funktion samt Rückgabetyp in A war eine Vorgabe und sollte nicht verändert werden.Wenn eine zu überschreibende Methode in Base einen vector<Base*> liefert (keine gute Idee), dann muss die überschreibende Methode in Derived ebenfalls einen vector<Base*> liefern. Befüllen kannst du den vector in Derived ja auch mit Derived*, da es wie gesagt eine Konvertierung von Derived* nach Base* gibt.
-
Stimmt, so scheint es zu gehen!!
Vielen Dank. Ein Spitzen-Forum mit Spitzen-Leuten!