Vererbung
-
danke für die hilfe

aber jetzt meckert das programm rum, wenn ich die minimale Leihgebühr ausgeben will.
Er sagt mir, dass irgendwas mit dem ostream nicht hinhaut:
Unresolved external 'operator <<(_STL::basic_ostream<char, _STL::char_traits<char> >&, KFZ

-
cout << "KFZ mit minimaler Leihgebühr: " << **iMin << endl;Kurt
-
jetzt meint er:
E2094 'operator<<' ist im Typ 'ostream' für Argumente des Typs 'KFZ' nicht implementiertich werde noch wahnsinnig ^^
-
Du hast zwar den operator<<(ostream&,Kfz*) als friend deiner Klasse deklariert, aber du hast ihn nicht definiert (sprich: Der Compiler weiß, daß es ihn gibt, aber nicht was er machen soll). Das führt dann zu dem genannten Linker-Fehler.
Und einen operator<<(ostream&,Kfz&) gibt es überhaupt nicht, wie dein Compiler richtig erkannt hat.
-
also in etwa so?
ostream& operator<<(ostream& out, KFZ* kfz)
{
string herst = (*kfz).hersteller;
float leihg = (*kfz).leihgebuehr;
out<<herst<<", "<<leihg;
return out;
}dann stürzt er aber mit der Fehlermeldung:
"... Exeption der Klasse EAccess Violation aufgetreten ..."
ab?!
-
In Deinem Programm oben
Mr. Blonde schrieb:
ich habe folgendes Programm geschrieben:
// dekl.h class KFZ { private: string hersteller; float leihgebuehr; public: KFZ(string herst, float leihg); friend ostream& operator<<(ostream& out, KFZ* kfz); // <- hier virtual string status()=0; };Hast Du einen Ausgabe-Operator für KFZ* definiert, aber keine Implementierung hinzugefügt. D.h., wenn Du die Methode AUTOVERLEIHER::ausgabe() aufrufst - mit der Erweiterung der minimalen Leihgebühr oder nicht, spielt keine Rolle - so meckert der Linker zu Recht die fehlende Implementierung an.
Überlicherweise schreibt man
friend ostream& operator<<(ostream& out, const KFZ& kfz );also die Ausgabe der KFZ und nicht dessen Pointer. Eine Implementierung könnte dann so aussehen:
ostream& operator<<(ostream& out, const KFZ& kfz ) { kfz.print( out ); return out; }und 'print' wird zu einer virtuellen Methode von KFZ
class KFZ { protected: virtual void print( std::ostream& out ) =0; // pur virtual; muss überladen werden // ...die von jeder abgeleiteten Klasse überschrieben werden muss. Z.B.:
class PKW : public KFZ { protected: virtual void print( std::ostream& out ) { out << "Pkw " << tueren << "'türig"; }Der Aufruf der Ausgabe von einem Iterator aus list< KFZ* > ist dann so, wie schon von ZuK geschrieben.
Gruß
Werner
-
Sorry. Ich sollte genauer lesen bevor ich Unsinn poste.
Kurt
-
ZuK schrieb:
Sorry. Ich sollte genauer lesen bevor ich Unsinn poste.
Hallo Kurt,
behaupte einfach, Du hast mein Posting vorhergesehen ;). Dann passt es.
Gruß
Werner
-
Hallo, ich hab das Programm nochmal komplett umgemoddet:
dekl.h
#include <iostream> #include <list> #include <conio> #include <string> #include <vcl> class KFZ; class AUTOVERLEIHER { private: list<KFZ*>Kfzliste; public: ~AUTOVERLEIHER(); void aufnehmen(KFZ* kzf); KFZ* getMinladekapa(float ladekapazitaet); float getMinausleihgeb(); void anzeigen(); float getTueren(); }; class KFZ { private: string hersteller; float leihgebuehr; public: KFZ(const string& Kfzhersteller, float Kfzleihgeb); virtual ~KFZ(){}; //benötigt um basisklassen virtuell zu setzen void getProfil(); float getleihgebuehr(); }; // Klasse PKW -> erbt von KFZ Hersteller und Leihgebuehr class PKW : public virtual KFZ { private: int tueren; public: PKW(int Pkwtueren, const string& hersteller, float leihgebuehr); virtual void getProfil(); //wird virtual gesetzt aufgrund der mehrfachvererbung //ohne mehrfachvererbung, müsste nur in der Basisklasse //getProfile auf virtual gesetzt werden int gettueren(); }; class LKW : public virtual KFZ { private: float ladekapazitaet; public: LKW(float LKWladekapazitaet, const string& hersteller, float leihgebuehr); virtual void getProfil(); float getLadekapazitaet(); }; class KOMBI : public PKW, public LKW { public: KOMBI(const string& hersteller, float leihgebuehr, int tueren, float ladekapazitaet): KFZ(hersteller, leihgebuehr),PKW(tueren, hersteller, leihgebuehr), LKW(ladekapazitaet, hersteller, leihgebuehr){} };header:
#include "dekl.h" #include <typeinfo> //#include <monsterKI.brain> KFZ::KFZ(const string& Kfzhersteller, float Kfzleihgeb) { this->hersteller = Kfzhersteller; this->leihgebuehr = Kfzleihgeb; } void KFZ::getProfil() { string TypeName = typeid(*this).name(); cout<<TypeName<<endl; cout<<"Hersteller: "<<this->hersteller<<" Leihgebuehr: "<<this->leihgebuehr; } float KFZ::getleihgebuehr() { return (this->leihgebuehr); } PKW::PKW(int Pkwtueren, const string& hersteller, float leihgebuehr) : KFZ(hersteller, leihgebuehr) { this->tueren = Pkwtueren; } int PKW::gettueren() { return (this->tueren); } void PKW::getProfil() { KFZ::getProfil(); cout<<" Tueren: "<<this->tueren<<endl; } // nächstes dingsbums LKW::LKW(float Lkwladekapazitaet, const string& hersteller, float leihgebuehr) : KFZ(hersteller, leihgebuehr) { this->ladekapazitaet = Lkwladekapazitaet; } float LKW::getLadekapazitaet() { return (this->ladekapazitaet); } void LKW::getProfil() { KFZ::getProfil(); cout<<" Ladekapazitaet: "<<this->ladekapazitaet<<endl; } void AUTOVERLEIHER::aufnehmen(KFZ* kfz) { Kfzliste.push_back(kfz); } float AUTOVERLEIHER::getTueren() { float gte = 1000; list<KFZ*>::iterator beginn = Kfzliste.begin(); list<KFZ*>::iterator ende = Kfzliste.end(); for(list<KFZ*>::iterator iter=beginn; iter != ende; iter++) { PKW *pkw = dynamic_cast<PKW*>(*iter); if(pkw && ((*pkw).gettueren() < gte)) { gte = (*pkw).gettueren(); } } return gte; } void AUTOVERLEIHER::anzeigen() { list<KFZ*>::iterator beginn = Kfzliste.begin(); list<KFZ*>::iterator ende = Kfzliste.end(); for(list<KFZ*>::iterator iter=beginn; iter != ende; iter++) { (**iter).getProfil(); } } AUTOVERLEIHER::~AUTOVERLEIHER() { list<KFZ*>::iterator beginn = Kfzliste.begin(); list<KFZ*>::iterator ende = Kfzliste.end(); for(list<KFZ*>::iterator iter=beginn; iter != ende; iter++) { delete *iter; } Kfzliste.clear(); } //Minimale Leihgebühr float AUTOVERLEIHER::getMinausleihgeb() { float me = 1000; list<KFZ*>::iterator beginn = Kfzliste.begin(); list<KFZ*>::iterator ende = Kfzliste.end(); for(list<KFZ*>::iterator iter=beginn; iter != ende; iter++) { PKW *pkw = dynamic_cast<PKW*>(*iter); if(pkw && ((*pkw).getleihgebuehr() < me)) { me = (*pkw).getleihgebuehr(); } } return me; }main:
#pragma hdrstop #include "impl.cpp" #pragma argsused int main(int argc, char* argv[]) { AUTOVERLEIHER a1; PKW * p1 = new PKW(6, " BMW", 1500); PKW * p2 = new PKW(4, " Renault", 500); PKW * p3 = new PKW(2, " XXX", 3000); LKW *l1 = new LKW(50," LKW",400); LKW *l2 = new LKW(30," W",600); LKW *l3 = new LKW(2,"H",3000); KOMBI * k1 = new KOMBI("AK", 27.50,3,500); a1.aufnehmen(dynamic_cast<KFZ*>(p1)); a1.aufnehmen(dynamic_cast<KFZ*>(p2)); a1.aufnehmen(dynamic_cast<KFZ*>(p3)); a1.aufnehmen(dynamic_cast<KFZ*>(l1)); a1.aufnehmen(dynamic_cast<KFZ*>(k1)); a1.anzeigen(); cout<<a1.getTueren()<<endl; cout<<a1.getMinausleihgeb(); getch(); return 0; }nun meine frage: wie kann ich realisieren, dass ein KFZ mit einer Ladekapazität von z.B. 2 angezeigt wird?!
thx im voraus

-
Mr. Blonde schrieb:
nun meine frage: wie kann ich realisieren, dass ein KFZ mit einer Ladekapazität von z.B. 2 angezeigt wird?!
Schlecht. Da die Klasse AUTOVERLEIHER nur eine liste von Pointern auf KFZ speichert kannst du auch nur auf Variablen und Methoden zugreifen die in KFZ vorhanden sind und KFZ weiss nichts von einer Ladekapazität.
Du könntest eventuell KFZ eine pure virtuelle Methode getLadeKapazitaet() geben und bei PKW immer 0 zurückgeben.
Kurt
-
mhhh ... kay
hab nochmal ne frage:
header:
#include <string> #include <iostream> #include <stdio> #include <list> //hochschulangehörige class HA { public: HA(string Name, string Vorname); friend ostream& operator<<(ostream& out, HA * ha); virtual string status() = 0; private: string HAName; string HAVorname; }; //studenten class S:public HA { public: S(string Name, string Vorname, int MatrikelNummer); int getMatrNr(); string status(); private: int matrNr; }; //mitarbeiter class MA:public HA { public: float mg(); string status(); MA(string Name, string Vorname, float Monatsgehalt); private: float monatsgehalt; }; //hilfsklasse für suche nach matrikelnummer class Funktor { public: Funktor(MatrikelNummer); bool operator() (HA * ha); private: int matrNr; }; //personalverwaltung class PV { public: void hinzu(string Name, string Vorname, int MatrikelNummer); void hinzu(string Name, string Vorname, float Monatsgehalt); void hinzu(HA * ha); void ausgabe(); HA * maxMg(); HA * sucheStudent(int MatrikelNummer); ~PV(); private: list<HA *> PersonenListe; };dekl:
#include "dekl.h" #include <string> #include <typeinfo> #include <vcl> //HOCHSCHULANGEHÖRIGER HA::HA(string Name, string Vorname) { this->HAName = Name; this->HAVorname = Vorname; } //MITARBEITER MA::MA(string Name, string Vorname, float Monatsgehalt) : HA(Name, Vorname) { this->monatsgehalt = Monatsgehalt; } float MA::mg() { return this->monatsgehalt; } string MA::status() { string typeInfo = typeid (*this).name(); return typeInfo + " " + FloatToStr(this->monatsgehalt).c_str(); } //STUDENT S::S(string Name, string Vorname, int MatrikelNummer):HA(Name, Vorname) { this->matrNr = MatrikelNummer; } int S::getMatrNr() { return this->matrNr; } string S::status() { string typeInfo = typeid(*this).name(); return typeInfo + " " + IntToStr(this->matrNr).c_str(); } //PERSONALVERWALTUNG //hinzufühen student void PV::hinzu(string Name, string Vorname, int MatrikelNummer) { this->PersonenListe.push_back(dynamic_cast<HA*>(new S(Name, Vorname, MatrikelNummer))); } //hinzufügen mitarbeiter void PV::hinzu(string Name, string Vorname, float Monatsgehalt) { this->PersonenListe.push_back(dynamic_cast<HA*>(new MA(Name, Vorname, Monatsgehalt))); } //ha hinzufügen void PV::hinzu(HA * ha) { PersonenListe.push_back(ha); } //ausgabe der kompletten hochschulangehörigenliste void PV::ausgabe() { list<HA*>::iterator beginn = this->PersonenListe.begin(); list<HA*>::iterator ende = this->PersonenListe.end(); for (list<HA*>::iterator iter = beginn;iter!=ende;iter++) { cout<<*iter<<'\n'<<(*iter)->status()<<'\n'; } } //suche maximales monatsgehalt HA * PV::maxMg() { HA * returnha=NULL; float MaxMG = -1; list<HA*>::iterator beginn = this->PersonenListe.begin(); list<HA*>::iterator ende = this->PersonenListe.end(); for (list<HA*>::iterator iter = beginn;iter!=ende;iter++) { MA * ma = dynamic_cast<MA*>(*iter); if (ma && ((*ma).mg() > MaxMG)) { MaxMG = (*ma).mg(); returnha = *iter; } } return returnha; } //suche student über matrikelnummer HA * PV::sucheStudent(int MatrikelNummer) { Funktor Fkt(MatrikelNummer); list<HA*>::iterator iter = find_if(PersonenListe.begin(), PersonenListe.end(), Fkt); if (iter == PersonenListe.end() || iter == NULL) throw MatrikelNummer; else return *iter; } //destruktor personalverwaltung PV::~PV() { list<HA*>::iterator beginn = this->PersonenListe.begin(); list<HA*>::iterator ende = this->PersonenListe.end(); for (list<HA*>::iterator iter=beginn; iter != ende; iter++) { delete *iter; } PersonenListe.clear(); } //hilfsfunktion für suche matrikelnummer Funktor::Funktor(int MatrikelNummer) { this->matrNr = MatrikelNummer; } bool Funktor::operator() (HA * ha) { S * s = dynamic_cast<S*>(ha); if (s && (*s).getMatrNr()==this->matrNr) { return true; } return false; } //überladen ausgabeoperator -> ostream... ostream& operator<<(ostream& out, HA * ha) { string Name = (*ha).HAName; string Vorname = (*ha).HAVorname; out<<Name<<", "<<Vorname; return out; }main:
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <conio> #include <stdio> #include "impl.cpp" #pragma hdrstop #pragma argsused int main(int argc, char* argv[]) { PV pv; //personalverwaltung schaffen //hinzufügen studenten pv.hinzu("Schulze","Edgar",970123); pv.hinzu("Werder","Jana",930897); pv.hinzu("Hartung","Mark",970235); //hinzufügen MA (durch float automatisch) pv.hinzu("Otto","Walter",(float)3500); pv.hinzu("Neumeier","Regina",(float)1000); pv.hinzu("Engelhardt","Barbara",(float)2500); //ausgeben aller hochschulangehöriger pv.ausgabe(); if (pv.maxMg() != NULL) { printf("\n\nmax MG : "); cout<<pv.maxMg()<<endl<<endl; } //suche nach matrikelnummer und rückgabe int MatrikelNummer = -1; cout<<"MatrikelNummer eingeben : "; cin>>MatrikelNummer; try { HA * ha = pv.sucheStudent(MatrikelNummer); cout<<ha; } catch (int e) { cout<<"kein Eintrag!"; } getch(); return 0; }wie kann ich erreichen, dass ich nicht über die matrikelnummer den namen suchen kann, sondern über den namen die matrikelnummer - muss doch irgendwie machbar sein
thx im voraus

-
Mr. Blonde schrieb:
wie kann ich erreichen, dass ich nicht über die matrikelnummer den namen suchen kann, sondern über den namen die matrikelnummer - muss doch irgendwie machbar sein
Indem du eine entsprechende Funktorklasse schreibst, die im Konstruktor den Namen übergeben bekommt - und dann die gefundenen Einträge nach Student castest.
(PS: eine kleine Bitte: verwende bitte in Zukunft cpp-Tags statt cs-Tags, dann passt das auch mit dem Syntax-Highlighting ;))