I/O operatoren überladen



  • 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.


Anmelden zum Antworten