virtual macht nicht was es soll



  • Ich habe ein Problem mit virtual. Ich will, dass das Objekt der Baseclass eine Methode der Subclass verwendet. Wie kann man das realisieren. Ich habs mal mit virtual probiert. Er ruft aber immer wieder die Methode der Oberklasse auf. Hab ich virtual nicht richtig verstanden?

    Ausgangssituation:

    class Baseclass{
    Baseclass() {...}
    virtual ~Baseclass(){..}
    virtual double funktion(){}
    };
    class Subclass:public Baseclass{
    Subclass(){...}
    ~Subclass(){...}
    virtual double funktion() {Code den ich verwenden will}
    };
    
    int main() {
    Baseclass p = Baseclass();
    cout << p.funktion() << endl;
    }
    

    Mit diesem Code verwendet er aber funktion() aus der Baseclass und nicht aus der Subclass. Was mache ich falsch?



  • class Baseclass{
    Baseclass() {...}
    virtual ~Baseclass(){..}
    virtual double funktion(){}
    };
    class Subclass:public Baseclass{
    Subclass(){...}
    ~Subclass(){...}
    virtual double funktion() {Code den ich verwenden will}
    };
    
    int main() {
    Baseclass * p = new Subclass()
    cout << p->funktion() << endl;
    }
    


  • MasterG87 schrieb:

    class Baseclass
    {
      Baseclass() {...}
      virtual ~Baseclass(){..}
      virtual double funktion(){}
    };
    class Subclass:public Baseclass
    {
      Subclass(){...}
      ~Subclass(){...}
      virtual double funktion() {Code den ich verwenden will}
    };
    
    int main() {
      Baseclass p = Baseclass();
      cout << p.funktion() << endl;
    }
    

    Dass Du hier ein paar mal "public:" vergessen hast, ignoriere ich.

    In main steckt schonmal ein dicker Fehler, der von megaweber korrekt erkannt wurde (Stichwort "slicing"). Den hätte ich auf anhib gar nicht gesehen. Ich habe nämlich schon bei diesem Thread-Titel erwartet, dass Du eine virtuelle Funktion von einem Konstruktor oder Destruktor aus aufrufen willst und erwartest, damit in der abgeleiteten Klasse zu landen. Dem ist nämlich nicht so.

    Wenn der Konstruktor der Basisklasse läuft, gibt es noch kein Subclass-Teil.
    Wenn der Destruktor der Basisklasse läuft, gibt es kein Subclass-Teil mehr.
    Wenn also die Funktion der abgeleiteten Klasse aufgerufen werden würde, würde die eventuell auf ungültige Daten zugreifen. Das will man nicht. Deswegen verhält es sich so, als wäre der dynamische Typ zur Zeit der Konstruktion/Destruktion ein anderer.

    kk



  • Da tritt kein Slicing auf, weil OP nirgendwo eine Instanz von Subclass erzeugt. funktion ist nicht pure-virtual und kann daher auch auf einer Instanz von Baseclass aufgerufen werden.



  • DocShoe schrieb:

    Da tritt kein Slicing auf

    Stimmt. Da steht ja nicht mal Subclass auf der rechten Seite. Ich schätze, das ist ein Abtipp-Fehler.



  • Ich habe den Code jetzt mal wie vorgeschlagen geändert:

    class Baseclass
    { public:
      Baseclass() {...}
      virtual ~Baseclass(){..}
      virtual double funktion(){}
    };
    class Subclass:public Baseclass
    { 
      public:
      Subclass(){...}
      virtual ~Subclass(){...}
      virtual double funktion() {Code den ich verwenden will}
    };
    
    int main() {
      Baseclass* p = new Subclass();
      cout << p->funktion() << endl;
    }
    

    Leider gibt er jetzt das Ergebnis von funktion() der Basisklasse aus. Ich möchte aber gern die funktion() in der Subclass verwenden. Wie kann ich das realisieren? Welche Möglichkeit habe ich mit einem Objektpointer der Basisklasse auf Methoden der Subclass zuzugreifen?



  • Die Fehlermeldung vom g++ Compiler ist übrigens gekürtzt die folgende:
    undefined reference to `vtable for Superquadric'



  • Sorry hab die Fehlermeldung nicht auf mein Kurzbeispiel angepasst:
    undefined reference to `vtable for Subclass'



  • Deine Angaben passen nicht zusammen, wenn der Linker eine undefined reference hat, kann das Programm nichts ausgeben, weil es nichtmal vollständig kompiliert worden ist.

    Die Fehlermeldung an sich bedeutet meistens, dass der Linker die Quelltextdatei, in der der virtuelle Destruktor implementiert ist, nicht sieht (oder die Implementieren desselben ganz fehlt).



  • MasterG87 schrieb:

    Leider gibt er jetzt das Ergebnis von funktion() der Basisklasse aus.

    Nö, der gibt so garnichts aus, nur Compilezeitfehler, dass Baseclass::function() einen Wert zurückgeben muss, der Konstruktor keinen ordentlichen Code enthält (2mal) das selbe für die Destruktoren (2mal) und dass "Code den ich verwenden will" kein gültiger Code ist.
    Wenn man die besagten Fehler alle entfernt, bekommt man auch das richtige ergebnis:

    #include <iostream>
    using namespace std;
    
    class Baseclass
    { public:
      Baseclass() {}
      virtual ~Baseclass(){}
      virtual double funktion(){return 0;}
    };
    class Subclass:public Baseclass
    {
      public:
      Subclass(){}
      virtual ~Subclass(){}
      virtual double funktion() {return 1;}
    };
    
    int main() {
      Baseclass* p = new Subclass();
      cout << p->funktion() << endl; //ergibt 1
      delete p; //führe uns nicht mit Speicherlecks und anderen Fehlern in die Irre ;)
    }
    

    Gib uns bitte Code, der

    1. compiliert,
    2. den Fehler erzeugt den du auch bekommst, und
    3. auf das Wesentliche reduziert ist.

    Grade der letzte Punkt ist wichtig, damit sich überhaupt jemand den code anschaut und ihn überblicken kann - und weil beim Reduzieren häufig der Fehler schon gefunden wird.



  • MasterG87 schrieb:

    Sorry hab die Fehlermeldung nicht auf mein Kurzbeispiel angepasst:
    undefined reference to `vtable for Subclass'

    Bau dein Projekt nochmal neu, du hast irgendwas nicht auf dem aktuellen Stand.


Anmelden zum Antworten