Abstrakte Klassen - Vector



  • Moin Moin,

    in Java ist folgendes möglich:

    public abstract class Mitarbeiter {    
        public abstract double monatslohn();    
    }
    
    public class Manager extends Mitarbeiter {
        public double monatslohn() {
            return 100000.1;
        }
    }
    
    public class Angestellter extends Mitarbeiter {
        public double monatslohn() {
            return 1000.34;
        }
    }
    
    public static void main(String[] args) {
        Vector<Mitarbeiter> m = new Vector<Mitarbeiter>();
    
        m.add(new Manager());
        m.add(new Angestellter());
    
        for(int i=0; i< m.size(); i++) 
        {
           m.get(i).monatslohn();
        }
    }
    

    Ich habe also eine abstrakte Klasse Mitarbeiter und 2 davon abgeleitete Klassen Angestellter und Manager. In der main Methode kann ich nun einen Vector vom Typ Mitarbeiter erstellen und in diesen beliebige Unterklassen der Mitarbeiterklasse einfügen und was noch viel wichtiger ist, danach in der Schleife auf die jeweilige Methode der Unterklasse zugreifen. Eine Ausgabe liefert also dann:

    100000.1
    1000.34

    Wenn ich dasselbe allerdings nun in C++ probiere bekomm ich schon bei

    std::vector<Mitarbeiter> m;
    

    den Compilerfehler C2259: 'Mitarbeiter' : Instanz von abstrakter Klasse kann nicht erstellt werden.

    Meine Frage ist nun wie kann ich dies in C++ implementieren, wahrscheinlich ist eine abstrakte Klasse hier nicht der richtige Weg?

    mfg
    Kieselfiesel



  • std::vector<Mitarbeiter*> m;
    

    und dann mit new



  • Polymorphie funktioniert in C++ nur mit Zeigern. Du musst also dynamisch mit new Objekte erzeugen und in der Liste darauf Zeiger verwalten lassen. Dann klappt das auch alles so wie aus Java gewohnt.

    MfG SideWinder



  • ah ok thx 👍

    Problem gelößt!



  • BTW: delete der einzelnen Objekte nicht vergessen, vector kümmert sich nur um sein Zeiger-Array nicht um die Elemente auf die der Zeiger zeigt!

    MfG SideWinder



  • Insofern evtl. smart pointer benutzen.



  • Imho, und da steh ich nicht alleine, unnötiger Overhead. volkard hatte vor kurzem die Idee eingebracht std::vector für solche Sachen doch abzuleiten und VectorWithDynamicConent einen Destruktur verpassen der auch die Elemente deleted.

    MfG SideWinder



  • @sidewinder
    wurde das hier diskutiert? weisst du zufällig nen link?

    in etwa so?

    template<
        typename T_>
    struct PtrVector : public std::vector<T_>
    {
    	~PtrVector()
    	{
    		typename std::vector<T_>::iterator it;
    
    		for(it = this->begin(); it != this->end(); ++it)
    		    delete *it;
    	}
    };
    


  • Einfach mal in die neue boost Version schauen. Da gibts jetzt boost::ptr_vector, das nimmt prinzipiell Pointer auf und sorgt auch dafür das diese gelöscht werden, wenn man sie aus dem vector löscht. Alles das was std::vector fehlt. Dann kann man sich auch den Smartpointer sparen, wenn man den nicht vorhatte zu benutzen.

    http://www.boost.org/libs/ptr_container/doc/ptr_vector.html



  • @miller: Ja, genau so, bloß musst du noch sämtliche remove-Methoden ebenfalls neu schreiben. Wahrscheinlich ist es tatsächlich einfacher (und höchstwahrscheinlich performanter) Boost dafür herzunehmen. "Diskutiert" (siehs dir einfach mal an ;)) wurde das hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-119115.html

    BTW: Das neue Design das man ab 5-stelliger-Postinganzahl hat ist einfach atemberaubend. Endlich habe ich auch Zugang zu den schweizer Konten und der neue Enzo macht sich gut in der Garage 😃

    MfG SideWinder


Anmelden zum Antworten