Oberklasseinstanzen in Vektor: Wie casten



  • Hallo!

    Angenommen ich hab ein vector<Person>. Von Person erbt meinetwegen Angestellter. Ich packe ganz viele Angestellte in den Personenvektor.
    Wie könnte ich z.B. sein Gehalt ausgeben?

    for(int i=0; i<personen.size() ++i)
    {
         cout<<(Angestellter)personen[i].gehalt<<endl; // Geht nicht
    }
    


  • Ich hab noch mal gegoogelt. Das das mit Pointern geht ist mir bekannt.
    Aber ich wollt's gerne mit Instanzen machen.



  • for(int i=0; i<personen.size() ++i)
    {
         cout << dynamic_cast<Angestellter>(personen[i]).gehalt << endl;
    }
    

    Aber vorsicht, das wirft ein std::bad_cast, wenn der cast nicht geht!



  • Es geht schlicht nicht.
    Das nennt man Slicing und bedeuted, dass wenn Du ein Angestellter in dein vector tust, eine Person konstruiert wird, die weiss aber nichts mehr vom Angestellten.

    Simon



  • das geht garnicht. Der vector speichert einzig un allein Personen ab. Wenn du ihm einen Angestellten übergibst, wird nur der Personen-Teil im vector gespeichert. (nennt sich slicing) Wenn du polymorphe Objekte in einem Container speichern willst geht das nur über Pointer in der einen oder andern Art (normale Pointer, smart-Pointer, Pointercontainer...)

    /edit: zu spät...



  • TGGC schrieb:

    Man gibt Person eine virtuelle Funktion int GetGehalt(){ return 0;} und implementiert die Angestellter entsprechend.

    Was hat GetGehalt in Person zu suchen?
    Warum will man überhaupt Angestellten-spezifische Funktionen auf Objekten aufrufen, die man nur über einen vector<Person*> oder boost::ptr_vector<Person> erreicht?

    Klingt nach Fehl-Design, um ehrlich zu sein.



  • pumuckl schrieb:

    das geht garnicht. Der vector speichert einzig un allein Personen ab. Wenn du ihm einen Angestellten übergibst, wird nur der Personen-Teil im vector gespeichert. (nennt sich slicing) Wenn du polymorphe Objekte in einem Container speichern willst geht das nur über Pointer in der einen oder andern Art (normale Pointer, smart-Pointer, Pointercontainer...)

    /edit: zu spät...

    Wobei ich gerade gelesen habe, dass man z.B. smart_ptr nicht in Vektoren/Listen usw. verwenden soll



  • klammer78 schrieb:

    Angenommen ich hab ein vector<Person>. Von Person erbt meinetwegen Angestellter. Ich packe ganz viele Angestellte in den Personenvektor. Wie könnte ich z.B. sein Gehalt ausgeben?

    Du versuchst in C++ Java zu programmieren, was eine ganz schlechte Idee ist. Anscheinend hast Du einen wichtigen Unterschied zwischen C++ und Java übersehen. In Java erreicht man Objekte nur über "Java-Objekt-Referenzen" (also immer indirekt), in C++ gibt es diese implizite Indirektion nicht. Indirektion ist explizit (siehe Zeiger, C++-Referenzen).

    class foo {
    public:
      int i;
      foo(int i) : i(i) {}
    };
    
    void direkt() {
      foo f1 = 23;
      foo f2 = f1;  // Kopie von f1
      f1.i = 42;
      cout << f2.i; // 23
    }
    
    void indirekt() {
      foo  f1 = 23;
      foo* f2 = &f1;
      f1.i = 42;
      cout << f2->i; // 42
    }
    

    Nur mit Indirektion funktioniert Polymorphie. Du solltest auch nicht vergessen, den Destruktor einer Basisklasse virtuell zu machen, falls Du abgeleitete Objekte über einen Zeiger auf die Basisklasse löschen willst.


Log in to reply