Vererbung: No matching function call
-
Ich habe folgende Basisklasse definiert:
// strom.h #include <iostream> #include <string> using namespace std; #ifndef __STROM_H__ #define __STROM_H__ class Strom { private: string quelle; unsigned int kWH; public: Strom(); Strom(string, unsigned int); void setQuelle(const string&); void setKWh(unsigned int); string getQuelle() const; unsigned int getkWH() const; void print() const; }; #endif
// strom.cpp #include <iostream> #include <string> #include "strom.h" using namespace std; Strom::Strom() : quelle(""), kWH(0) { } Strom::Strom(string quelle, unsigned int kWH) : quelle(quelle), kWH(kWH) { } void Strom::setQuelle(const string &quelle) { this->quelle = quelle; } void Strom::setKWh(unsigned int kWH) { this->kWH = kWH; } string Strom::getQuelle() const { return this->quelle; } unsigned int Strom::getkWH() const { return this->kWH; } void Strom::print() const { cout << "Stromquelle: " << getQuelle() << endl; cout << "KWh: " << getkWH() << endl; }
// atomkraft.h #include <iostream> #include <string> #include "strom.h" using namespace std; #ifndef __ATOMKRAFT_H__ #define __ATOMKRAFT_H__ class Atomkraft : public Strom { private: unsigned int co2KWh; float ct4KWh; public: Atomkraft(unsigned int, float, string, unsigned int); unsigned int getCo2KWh() const; float getCt4KWh() const; void setCo2KWh(unsigned int); void setCt4KWh(float); void print() const; }; #endif
// atomkraft.cpp #include <iostream> #include <string> #include "atomkraft.h" using namespace std; Atomkraft::Atomkraft(unsigned int co2KWh = 0, float ct4KWh = 0.0, string quelle = "", unsigned int kWh = 0) : Strom (quelle, kWh), co2KWh(co2KWh), ct4KWh(ct4KWh) { } unsigned int Atomkraft::getCo2KWh() const { return this->co2KWh; } float Atomkraft::getCt4KWh() const { return this->ct4KWh; } void Atomkraft::setCo2KWh(unsigned int co2KWh) { this->co2KWh = co2KWh; } void Atomkraft::setCt4KWh(float ct4KWh) { this->ct4KWh = ct4KWh; } void Atomkraft::print() const { cout << "CO2 pro KWh: " << this->getCo2KWh() << endl; cout << "Cent pro KWh: " << this->getCt4KWh() << endl; Strom::print(); }
#include <iostream> #include <string> #include "atomkraft.h" using namespace std; int main() { Atomkraft meiler1; return 0; }
Wenn ich versuche das zu kompilieren
g++ -Wall -pedantic-errors strom.cpp atomkraft.cpp main.cpp -o strom
bekomme ich die Fehlermeldung
main.cpp:8:12: error: no matching function for call to ‘Atomkraft::Atomkraft()’
Wieso???
Es wird doch ein passender Konstruktor ohne Argumente bereitgestellt.
-
GetIT schrieb:
Es wird doch ein passender Konstruktor ohne Argumente bereitgestellt.
Wo?
-
Es wird doch public von der Elternklasse geerbt.
Und die Elternklasse stellt doch einen passenden Konstruktor zur Verfügung?!
-
GetIT schrieb:
Es wird doch public von der Elternklasse geerbt.
Und die Elternklasse stellt doch einen passenden Konstruktor zur Verfügung?!Der einen Strom konstruiert. Aber wie baut man einen Atomkraft? Konstruktoren werden aus gutem Grund nicht vererbt! Der Strom-Konstruktor kann nur den Strom-Teil einer Atomkraft bauen (und das geschieht auch automatisch), aber wie der Rest geht, muss noch definiert werden. Oder direkter gesagt: Wie soll der Strom-Konstruktor denn wissen, was er mit
co2KWh
undct4KWh
machen soll? Wieso möchtest du hier überhaupt einen argumentenlosen Konstruktor benutzen, wenn du doch den schönen Atomkraftkonstruktor hast, der alles richtig initialisiert? Ein Konstruktor sollte ein fertig verwendungsfähiges Objekt erzeugen. Ich sehe nicht, wie ein argumentenloser Konstruktor von Atomkraft dies leisten sollte. Schließlich gibt es keine sinnvollen Vorgabewerte für die hier gefragten Parameter.Ich finde dein Klassendesign übrigens nicht so gelungen. Atomkraft ist ein Strom? Klingt komisch, oder? Und die auszeichnende Eigenschaft von Strom sind Quelle und Strommenge? Das klingt auch nicht gerade nach der Lexikondefinition von Strom. Der Unterschied zwischen allgemeinem Strom und Atomkraft ist, dass Atomkraft (im Gegensatz zu anderen Strömen) auch noch einen Preis und einen CO²-Wert hat? Haben das nicht alle Ströme (zumindest unter deiner Definition von Strom)?
CO²-Wert und Strommenge, von denen man doch eigentlich annehmen würde, dass sie beliebig fein unterteilbar sind, sind nur in ganzzahligen Schritten ausdrückbar? Klingt auch falsch. Hingegen ist ausgerechnet der Preis bei dir beliebig fein unterteilbar, wenn man doch aus der Realität eher kennt, dass Geldbeträge kleinsterweise in Cent oder Zehntelcent ausdrückbar sind.
-
Konstruktoren werden aus gutem Grund nicht vererbt!
Okay, das macht Sinn.
Aber wieso gehts dann, wenn ich alles Inline in den Headerfiles definiere?
Also so:// strom.h #include <iostream> #include <string> using namespace std; #ifndef __STROM_H__ #define __STROM_H__ class Strom { private: string quelle; unsigned int KWh; public: Strom():quelle(""),KWh(0) {} Strom(string q, unsigned k):quelle(q), KWh(k) {} void setQuelle(const string &q) { quelle = q; } void setKWh(unsigned int k) { KWh = k; } string getQuelle() const { return quelle; } unsigned int getKWh() const { return KWh; } void print() const { cout << "Stromquelle: " << getQuelle() << endl; cout << "KWh: " << getKWh() << endl; } }; #endif
// atomkraft.h #include <iostream> #include <string> #include "strom.h" using namespace std; #ifndef __ATOMKRAFT_H__ #define __ATOMKRAFT_H__ class Atomkraft : public Strom { private: unsigned int Co2KWh; float ct4KWh; public: Atomkraft(unsigned int co2=0, float ct=0.0, string q="", unsigned int k=0) : Strom(q, k), Co2KWh(co2), ct4KWh(ct) { }; unsigned int getCo2KWh() const { return Co2KWh; } float getct4KWh() const { return ct4KWh; } void setCo2KWh(unsigned int co) { Co2KWh = co; } void setct4KWh(float ct) { ct4KWh = ct; } void print() const { cout << "Co2 pro KWh : " << getCo2KWh() << endl; cout << "Cent pro KWh: " << getct4KWh() << endl; Strom::print(); } }; #endif
Das kann ich problemlos kompilieren.
Die main.cpp ist wie im ersten Beitrag.
-
Ich finde dein Klassendesign übrigens nicht so gelungen. Atomkraft ist ein Strom? Klingt komisch, oder?
Das mag ja alles sein.
Aber das ist ja auch nur nen Übungsbeispiel.
-
Das kann ich problemlos kompilieren.
Jetzt stehen die Defaultwerte der Parameter des Konstruktors im Header, wo sie hingehören. Der Rest kann bleiben wo er war.
-
GetIT schrieb:
Ich finde dein Klassendesign übrigens nicht so gelungen. Atomkraft ist ein Strom? Klingt komisch, oder?
Das mag ja alles sein.
Aber das ist ja auch nur nen Übungsbeispiel.
Normalerweise sind Übungsbeispiele dazu da, zu versuchen, es möglichst richtig zu machen.
Aber wieso gehts dann, wenn ich alles Inline in den Headerfiles definiere?
Weil du nun in Zeile 14 einen argumentenlosen Konstruktor definiert hast.
-
GetIT schrieb:
Ich finde dein Klassendesign übrigens nicht so gelungen. Atomkraft ist ein Strom? Klingt komisch, oder?
Das mag ja alles sein.
Aber das ist ja auch nur nen Übungsbeispiel.
Wenn man ableiten zum Üben betreibt, nimmt man Foo und Bar (oder etwas ähnlich nichts sagendes). Du übst eine völlig falsche Vorstellung vom Sinn des Ableitens ein.
-
Weil du nun in Zeile 14 einen argumentenlosen Konstruktor definiert hast.
Ich nehme mal an du meinst dieses Zeile in atomkraft.h
Atomkraft(unsigned int co2=0, float ct=0.0, string q="", unsigned int k=0) : Strom(q, k), Co2KWh(co2), ct4KWh(ct) { };
Also ich sehe hier 4Parameter - unsigned int, float, string und unsigned int.
Zeige mir doch bitte mal den Konstruktor ohne Argumente.
Danke
-
GetIT schrieb:
Zeige mir doch bitte mal den Konstruktor ohne Argumente.
Kannst man den gezeigten Konstruktor ohne Argumente aufrufen?
-
Der Konstruktor ist nicht ohne Argumente, aber hat ausschließlich Argumente mit Defaults. Du kannst ihn also mit () aufrufen.
In deiner ersten Variante fehlte dieser Konstruktor/Argumentliste im Header.
Manni66 schrieb doch bereits:
Jetzt stehen die Defaultwerte der Parameter des Konstruktors im Header, wo sie hingehören.
-
Vielen Dank!!