virtual member Funktion wird nicht aufgerufen



  • Im folgenden Beispiel wird nur die Funktion der Basisklasse nicht die der Überladenen Klasse aufgerufen (hier die Funktion length()) obwohl ich sie virtual deklariert habe.

    Ich habe folgende Klasse:

    class ABCD
    {
    public:
        // Constructors
        ABCD();
        ABCD(double A, double B, double C, double D);
    ...
         virtual double length();
    };
    
    double ABCD::length()
    {
        return 0;
    }
    

    und diese Klasse die von ABCD ableitet:

    class Space : public ABCD
    {
    public:
        Space();
        Space(double distance);
    
        void setDistance(double distance);
        double distance();
        double length();
    
    private:
        double m_distance;
    };
    
    double Space::length()
    {
        return distance();
    }
    

    ich füge nun diese Klassen in einen vector ein:

    propagation->addMatrix(Lens(focalLenght));
        propagation->addMatrix(Space(distance));
    
    void BeamPropagation::addMatrix(const ABCD & abcd)
    {
        d->matrixList.push_back(abcd);
    }
    

    der die Basisklassen entgegennimmt.

    Wenn ich nun die Länge der enthaltenen Matrizen aufrufe

    double BeamPropagation::zAxisSize(size_t elements)
    {
        double size = 0;
        for (size_t i = 0; i < elements; ++i)
        {
            size += d->matrixList.at(i).length();
        }
        return size;
    }
    

    dann wird immer length() von ABCD aufgerufen - was nicht das ist was ich möchte.

    Was aber mache ich falsch?



  • Was ist denn matrixList? Ein vector<ABCD>? Dann sind da auch nur ABCDs drin.



  • MFK schrieb:

    Was ist denn matrixList? Ein vector<ABCD>? Dann sind da auch nur ABCDs drin.

    Ja das ist ein vector<ABCD> matrixList;

    Würde das ganze funktionieren wenn ich es als

    vector<ABCD*> matrixList;
    

    deklarieren?



  • pospiech schrieb:

    Ja das ist ein vector<ABCD> matrixList;

    Dann wird beim Einfügen alles abgeschnitten, was nicht ABCD ist.

    pospiech schrieb:

    Würde das ganze funktionieren wenn ich es als

    vector<ABCD*> matrixList;
    

    deklarieren?

    Benutz besser Smartpointer oder einen speziellen Zeiger-Container.



  • Ja das ist ein vector<ABCD> matrixList;

    *seufz*

    Gewöhne Dir an, polymorphe Basisklassen abstrakt zu machen. Damit kannst Du viele solche Fehler ausschließen.

    vector<ABCD*> matrixList; // ?

    Brauchst Du wirklich hier polymorphe Klassen? (Denk nochmal über Dein Design nach) Musst Du sie wirklich in einem Container speichern, der die konkreten Typen nicht kennt? Wenn Du beides mit ja beantwortest, ist vielleicht ein boost::ptr_vector sehr nützlich. Oder vector<shared_ptr<ABCD> >.



  • krümelkacker schrieb:

    Wenn Du beides mit ja beantwortest, ist vielleicht ein boost::ptr_vector sehr nützlich. Oder vector<shared_ptr<ABCD> >.

    Hier möchte ich noch eines hinzufügen:

    Falls der Container die Elemente "besitzt" (Mit dem löschen des Containers sollen die Elemente auch gelöscht werden), würde ich zum boost::ptr_vector greifen, und nur wenn dies nicht der Fall ist zu der letzteren Version (shared_ptr ist "teurer", und trotz seines Nutzens sollte man ihn daher mit Bedacht einsetzen - was nicht heißt das man ich gänzlich meiden soll).


Anmelden zum Antworten