006
29.01.2018, 10:07 Uhr
ao
(Operator)
|
Du hast der Klasse Ficus einen Konstruktor gegeben, der einen float-Parameter erwartet und damit implizit den Default-Konstruktor entfernt.
In C++ gilt die Regel, dass jeder Konstruktor einer abgeleiteten Klasse (hier LuxusFicus) einen Konstruktor der Basisklasse (Ficus) aufruft, und zwar entweder den, der explizit angegeben wird (siehe unten) oder, falls keiner angegeben wird, den Default-Konstruktor. Diesen hast du aber bei Ficus aufgehoben.
Um den Fehler abzustellen, musst du nun: * entweder einen (parameterlosen) Default-Konstruktor Ficus::Ficus() schreiben. Dieser wird dann vom Default-Konstruktor LuxusFicus::LuxusFicus() verwendet. Vorsicht: Dadurch entstehen Pflanze-Instanzen, deren Member (groesse, maxgroesse, giftig) nicht initialisiert sind und daher Zufallswerte enthalten. * oder einen Konstruktor LuxusFicus::LuxusFicus(float g) schreiben, der den g-Parameter an Ficus::Ficus(float g) weitergibt, nämlich so:
C++: |
class LuxusFicus : public Ficus{ public: LuxusFicus () : Ficus (1.80) {} // Default-Konstruktor initialisiert Ficus auf 1,80 m };
|
Das beruhigt zwar den Compiler, ist aber wahrscheinlich nicht besonders sinnvoll.
Du hast weiter oben einen Designfehler gemacht: Die Basisklasse (Zimmerpflanze) hat keinen Init-Code für die eigenen Member, d.h. sie verlässt sich drauf, dass die Ableitungen sie richtig initialisieren werden. Daran musst du bei jeder weiteren Zimmerpflanze-Ableitung denken.
Über sowas wirst du garantiert früher oder später stolpern. Spätestens dann, wenn dein Projekt so groß geworden ist, dass du nicht mehr jede Kleinigkeit im Kopf haben kannst oder gar einen Mitarbeiter einstellst (ja ich weiß, du spielst nur herum, aber das sind die Dinge, die ein gutes Design ausmachen: Dass man den Klassen ansieht, wie sie zu benutzen sind).
Empfehlung: Gib der Zimmerpflanze einen Konstruktor, der bei der Ableitung die Angabe der benötigten Daten verlangt:
C++: |
#include <iostream>
using namespace std;
class Zimmerpflanze{ protected:
float groesse; int maxgroesse; bool giftig; public: // Dieser Konstruktor verlangt die wichtigen drei Parameter. // Gleichzeitig wird der Default-Konstruktor entfernt, d.h. // eine Ableitung mit Zimmerpflanze::Zimmerpflanze() ist // nicht mehr möglich. Zimmerpflanze (float groesse_, int maxgroesse_, bool giftig_) : groesse (groesse_) , maxgroesse (maxgroesse_) , giftig (giftig_) { } };
class Ficus : public Zimmerpflanze{
public: Ficus(float g) : Zimmerpflanze (g, 300, false) // Hier wird die Zimmerpflanze initialisiert. { } float PreisBerechnen(){ return (5+10*groesse); } };
class LuxusFicus : public Ficus{ public: LuxusFicus (float groesse_) : Ficus (groesse_) {} };
int main() { Ficus F1(1.20); F1.PreisBerechnen(); LuxusFicus L1 (1.80); L1.PreisBerechnen(); cout << "Ficus Preis : " << F1.PreisBerechnen() << endl; cout << "Luxus Preis : " << F1.PreisBerechnen() << endl;
return 0; }
|
|