Problem mit virtuellen Funktionen



  • Hallo ich habe folgendes Problem:

    class DataBase; // forward (abstract class)
    
    class ConcreteData : public DataBase;
    //Rest ist mal weggellassen...
    
    class Base
    {
    ...
    public:
      void setData(DataBase& data) = 0;
    ...
    };
    
    class Derived : public base
    {
    public:
      void setData(ConcreteData& aData) { data = aData; }
    private:
      ConcreteData data;
    }
    

    Alleine bei diesem Beispiel meckert der compiler (vc.net 2003), dass die rein virtuelle Methode setData nicht implementiert ist.
    Ich könnte anstelle von ConcreteData& auch DataBase& verwenden. Dann muesste ich allerdings einen =operator schreiben der DataBase& als Parameter nimmt.
    Stehe gerade auf dem Schlauch...



  • Hallo,
    C++ unterstützt nur kovariante Rückgabewerte nicht aber kovariante Parameter. Um eine virtuelle Methode zu überschreiben musst du also identische Parameter-Typen angeben. In deinem Fall also DataBase.



  • Desweiteren hat die Basisklasse kein einziges virtuelles Mitglied, womit die Klassen nichtmal polymorphisch sind...

    (Mach dir nix draus bin ich selbst erst kürzlich übel drauf reingefallen :D)



  • LordJaxom schrieb:

    Desweiteren hat die Basisklasse kein einziges virtuelles Mitglied, womit die Klassen nichtmal polymorphisch sind...

    Was heißt virtuelles Mitglied und was hat es für folgen, dass sie nicht Polymorphisch sind?



  • Polymorphie macht es überhaupt erst möglich dass die Funktion der abgeleiteten Klasse verwendet wird wenn der Typ des Objekts von der abgeleiteten Klasse ist. Der Sinn ist ja, dass ich auf ein Base& (welches in Wirklichkeit ein Objekt vom Typ Derived ist) die Methode setData aufrufen kann, tatsächlich aber die Methode Derived::setData genutzt wird.

    Demnach macht

    void setData(DataBase& data) = 0;
    

    keinen Sinn, denn: Abstrakt, d.h. ein Aufruf dieser Methode würde zur Laufzeit einen Fehler geben "pure virtual called" und Nichtvirtuell, d.h. es wird beim Aufruf dieser Methode keine abgeleitete Klasse herangezogen -> Widerspruch also Fehler 🙂

    virtual void setData(DataBase& data) = 0;
    

    In der Ableitung steht es Dir frei, virtual hinzuschreiben oder wegzulassen, da virtual sich eh vererbt.



  • Danke

    virtual
    

    sollte man benutzen. Bin schon blind.
    Jetzt hab ich den setter so gemacht.

    class DataBase; // forward (abstract class)
    
    class ConcreteData : public DataBase;
    //Rest ist mal weggellassen...
    
    class Base
    {
    ...
    public:
      void setData(const DataBase& data) = 0;
      AddressAC& getData() const;
    ...
    };
    
    class Derived : public base
    {
    public:
      void setData(const DataBase& aData) { setData(static_cast<const ConcreteData&>(aData)); }
      void setData(ConcreteData& aData) { data = aData; }
      ConcreteData &getData() const { return data; }
    private:
      ConcreteData data;
    }
    

    Jetzt sieht man auch den Unterschied schön kovarianter Rückgabewert/Paramter. Danke!


Anmelden zum Antworten