I/O operatoren überladen
-
hi, ich hab nen problem bei dem überladen des ausgabe operators
und zwar hab ich ne main Klasse darin mach ich einen neuen Zoo "emmen" und da soll ich dann cout << *emmen machen und da soll er mir alle mitarbeiter aus dem zoo ausgeben. ich hab weiterhin ne klasse zoo, ne klasse arbeitnehmer worin 2 virtuelle methoden sind einmal die "ausgeben" um die informationen von dem arbeitnehmer auszugeben und die "gibGehalt". Weiterhin erben 3 Klassen von dieser. Manager, aufpasser, Admin.wenn ich jetz in der klasse arbeitnehmer
ostream & operator << (ostream & os, Arbeitnehmer & a){ os << a.ausgabe(); return os; }mach, funktioniert das nicht, er sagt mir was von void das das nicht geht. Weil wenn ich die methode a.gibGehalt() aufrufe funktioniert alles ohne probleme, weiterhin is das problem das wenn ich dieses in der Klasse ARbeitnehmer mach, kann ich ja nicht aus der Main cout<<*emmen anrufen, da müsst ich dann inder Zoo klasse auch noch so ne ähnliche funktion machen mit dem überladenen ausgabeoperator.
ich blicks einfach net...
pls help
-
MiMi85 schrieb:
hi, ich hab nen problem bei dem überladen des ausgabe operators
und zwar hab ich ne main Klasse darin mach ich einen neuen Zoo "emmen" und da soll ich dann cout << *emmen machen und da soll er mir alle mitarbeiter aus dem zoo ausgeben. ich hab weiterhin ne klasse zoo, ne klasse arbeitnehmer worin 2 virtuelle methoden sind einmal die "ausgeben" um die informationen von dem arbeitnehmer auszugeben und die "gibGehalt". Weiterhin erben 3 Klassen von dieser. Manager, aufpasser, Admin.wenn ich jetz in der klasse arbeitnehmer
ostream & operator << (ostream & os, Arbeitnehmer & a){ os << a.ausgabe(); return os; }mach, funktioniert das nicht, er sagt mir was von void das das nicht geht. Weil wenn ich die methode a.gibGehalt() aufrufe funktioniert alles ohne probleme, weiterhin is das problem das wenn ich dieses in der Klasse ARbeitnehmer mach, kann ich ja nicht aus der Main cout<<*emmen anrufen, da müsst ich dann inder Zoo klasse auch noch so ne ähnliche funktion machen mit dem überladenen ausgabeoperator.
ich blicks einfach net...
pls help
Wetten, dass Arbeitnehmer::ausgabe() ein void zurückgibt ?
... und ein void kann man nunmal nicht per "<<" ausgeben.
Ich glaube, Du mischst hier zwei verschiedene Konzepte, eigene Datentypen anzuzeigen:
Konzept A: Verpasse Deiner Klasse eine ausgabe()-Funktion (oder "show()" oder ...). Diese wird von Nutzer aufgerufen und fertig.Konzept B: Nutzer die Ausgabeoperatoren der Streams. Diese werden vom Nutzer verkettet wie
cout << "Dies ist ein CString" << i << " " << a << "\n";Ich persönlich bin ein Fan des Konzepts B und Du hast Dich ja schon auf den Weg dahin gemacht - aber leider nur halb.
Wahrscheinlich brauchst Du den Rumpf Deiner Ausgabe-Funktion in den operator<<() zu kopieren (und statt cout -> out verwenden).Gruß,
Simon2.
-
mhm ja.. da hast du wohl recht. also muss ich jetzt wohl alle ausgabe() in string umändern, wenn ich das richtig seh. mal probiern..
muss ich die methode
ostream & operator << (ostream & os, Arbeitnehmer & a)in jeder abgeleiteten klases vom arbeitnehmer einfügen oder nur in Arbeitnehmer selbst? und wie komm ich da von der main ran, weil in der klasse Zoo müsst ich ja dann auch noch was in der richtung haben, so das auch alle arbeitnehmer ausgegeben werden
-
MiMi85 schrieb:
mhm ja.. da hast du wohl recht. also muss ich jetzt wohl alle ausgabe() in string umändern, wenn ich das richtig seh. mal probiern.....
Hast Du denn mehrere ausgabe()-Funktionen in einer Klasse (overloading) ? Dann dürftest Du ein Problem haben, weil Du dem operator<<() ja nicht mitgeben kannst, welche er verwenden soll....
(Vermutlich meinst Du aber jeweils eine Ausgabefunktion in unterschiedlichen Klassen, oder ?)Ich würde nicht in strings packen, also den operator<<() die ausgabe() nutzen lassen, sondern andersherum:
// forward-deklarationen class Arbeitnehmer; ostream& operator<<(ostream& out, Arbeitnehmer const& a); class Arbeitnehmer { string name; public: void ausgabe() const { cout << *this << "\n"; } string const& getName() const { return name; } // Alternativ: operator<<() als friend deklarieren ... } ostream& operator<<(ostream& out, Arbeitnehmer const& a) { return out << a.name; }Vorteil: Mit ostreams kannst Du mehr machen (via ostringstream aufpolieren, in ofstreams wegschreiben, ....) u.a. auch strings draus machen.
Gruß,
Simon2.
-
mhm.. versteh ich nicht. a.name ist ja auch nen string, das kann ja nur funktioniern ^^ und den als friend gemacht hab ich schon.
in der klasse Arbeitnehmer.h hab ich jetzt
class Arbeitnehmer { friend ostream & operator << (ostream&, Arbeitnehmer &);in der klases Arbeitnehmer.cc hab ich jetzt
ostream & operator << (ostream & os, Arbeitnehmer& w){ os << w.ausgabe(); return os; }nur das geht nicht da ja die ausgabe funktion so aussieht
string Admin::ausgabe(){ //Arbeitnehmer::drukaf(); cout << "\t Gehalt(Admin1000+"<<alter()<<"*500): "<< gibGehalt() <<endl; }
-
ostream & operator << (ostream & os, const Arbeitnehmer& w){ os << "Gehalt(Admin1000+"<<alter()<<"*500): "<< gibGehalt(); return os; }.. und wirf die Methode 'ausgabe()' weg.
und wenn Du es ausgeben willst, dann schreibe:
Arbeitnehmer a; cout << a << endl;Gruß
Werner
-
naja im aufgabenbuch steht wir sollen das überladen des ausgabeoperators mit hilfe der ausgabefunktion machen. darum häng ich mich daran so fest...
-
MiMi85 schrieb:
naja im aufgabenbuch steht wir sollen das überladen des ausgabeoperators mit hilfe der ausgabefunktion machen. darum häng ich mich daran so fest...
OK,
klingt nach einer weiteren "sinnlos-weil-macht-man-in-der-Praxis-besser-anders-Aufgabe"

Dann ist das mit dem String (bzw. ostringstream) schon nicht schlecht.Gruß,
Simon2.
-
Simon2 schrieb:
klingt nach einer weiteren "sinnlos-weil-macht-man-in-der-Praxis-besser-anders-Aufgabe"

Dann ist das mit dem String (bzw. ostringstream) schon nicht schlecht.Huh? Wie sieht denn die Alternative aus der Praxis aus?
struct Arbeitnehmer { virtual void ausgabe( std::ostream& out ) const = 0; }; std::ostream& operator<<( std::ostream& out, Arbeitnehmer const& obj ) { obj.ausgabe(out); return out; } struct Manager : Arbeitnehmer { virtual void ausgabe( std::ostream& out ) const { out << "Manager!"; } }; struct Admin : Arbeitnehmer { virtual void ausgabe( std::ostream& out ) const { out << "Admin!"; } };
-
ok 2 fragen..
1. warum macht ihr immer überall nen const hin?
2. wofür steht das struct
-
MiMi85 schrieb:
1. warum macht ihr immer überall nen const hin?
Wegen der const-correctness!

(const bei Variablen/Parametern heisst dass diese nicht verändert werden können, bei Methoden dass sie das Objekt nicht ändert.)MiMi85 schrieb:
2. wofür steht das struct
Im Prinzip das Gleiche wie class, bloß dass alles per default public statt private ist.
-
Hi finix,
OK, ich hatte einerseits nur an die "Stringisierung" (sprich: erst alles in ausgabe() in einen String verwandeln und den dann im operator<< verwenden) und dafür nicht an Polymorphie gedacht.
Gruß,
Simon2.
-
MiMi85 schrieb:
...
1. warum macht ihr immer überall nen const hin?
...Es ist sicherer (und deswegen "guter Stil"), dem Compiler möglichst viel an die Hand zu geben, damit er helfen kann .... und letztlich schießt man sich mit zu wenig const ins Knie - spätestens, wenn man denn doch mal ein Konstantes Objekt in die Finger bekommt, es aber leider nicht verwenden kann.
Gruß,
Simon2.