Spätes Binden in Methode der Oberklasse



  • Hallo,

    ich habe zur Zeit folgendes Problem und weiß nicht so recht, wie ich es lösen soll. Die Klassenstruktur sieht in etwa folgendermaßen aus:

    class Oberklasse {
    public:
      Oberklasse() {}
    
      virtual int getValue() { return 0; }
      void myMethod()
      {
        printf("%i\n", getValue());
      }
    };
    
    class Kindklasse : public Oberklasse {
    public:
      Kindklasse() {}
    
      int getValue() { return 1; }
    };
    

    Wenn ich nun eine Instanz von Kindklasse habe und die Methode myMethod() aufrufe, soll erst zur Laufzeit entschieden werden, dass in diesem Fall in der Methode das getValue() der eigenen Instanz aufgerufen wird.
    So wie es jetzt ist, bekomm ich 0 zurückgeliefert, da immer die virtuelle Methode der Oberklasse gerufen wird.

    Gibt es eine Möglichkeit, das zu ändern?
    Ich hoffe, ihr könnt mir bei dem Problem behilflich sein. Dafür wäre ich echt dankbar. 🙂

    Grüße


  • Mod

    Das sollte eigentlich nicht so sein. Kannst du deinen konkreten Aufruf zeigen? Sind vielleicht irgendwelche Casts im Spiel?

    P.S.: Warum benutzt du printf?



  • Hallo,

    eine Funktion ist entweder virtuel oder inline. Beides ist meistens Unfug. Ich weiß zwar jetzt nicht, was der Standard in diesem Falle vorschreibt aber ich würde hier die Funktion ganz normal definieren.

    mfg Martin



  • Was machst du denn genau?

    #include<iostream>
    
    class Oberklasse {
    public:
      Oberklasse() {}
    
      virtual int getValue() { return 0; }
      void myMethod()
      {
        std::cout << getValue() << std::endl;
      }
    };
    
    class Kindklasse : public Oberklasse {
    public:
      Kindklasse() {}
    
      int getValue() { return 1; }
    };
    
    int main(){
            Oberklasse o1;
            Kindklasse o2;
            Oberklasse* p1 = &o1;
            Oberklasse* p2 = &o2;
            p1->myMethod();
            p2->myMethod();
            return 0;
    }
    

    liefert:

    0
    1

    Kann es sein, dass du in Wirklichkeit hinter einer der Funktionen ein const hast und hinter der anderen nicht?



  • Hm, ich hab meinen Beispielcode mal selbst ausprobiert und musste feststellen, dass es funktioniert. Nun frage ich mich, warum es in meinem konkreten Fall nicht klappt.

    printf hab ich jetzt nur aus Testzwecken benutzt. 😉
    Ich deklariere die Methode als virtuell, da ich mehrere Kindklassen habe und nur dadurch Polymorphie und somit spätes Binden gewährleistet ist. (nach meinem Wissensstand)

    Ich werd nochmal über meinen Code schauen und versuche herauszufinden, an was es liegen könnte. Ich meld mich nochmal, sobald ich mehr weiß. 🙂



  • Andere Vermutung: Du erstellst versehentlich irgendwo eine Kopie
    wie etwa in diesem Beispiel:

    #include<iostream>
    
    class Oberklasse {
    public:
      Oberklasse() {}
    
      virtual int getValue() { return 0; }
      void myMethod()
      {
        std::cout << getValue() << std::endl;
      }
    };
    
    class Kindklasse : public Oberklasse {
    public:
      Kindklasse() {}
    
      int getValue() { return 1; }
    };
    
    void print(Oberklasse ok){
            ok.myMethod();
    }
    
    int main(){
            Oberklasse o1;
            Kindklasse o2;
            Oberklasse* p1 = &o1;
            Oberklasse* p2 = &o2;
            p1->myMethod();
            p2->myMethod();
            print(*p1);
            print(*p2);
            return 0;
    }
    

    0
    1
    0
    0

    Mach dir mal ne Ausgabe in den Copy-Constructor



  • Ja, ich glaube an diesem oder einem ähnlichen Problem lag es.
    Ich hab die Methoden einfach nochmal geschrieben und dabei aufgepasst alles richtig zu machen.
    Manchmal ist man eben doch blind und findet den Fehler einfach nicht obwohl er vor der Nase liegt. ^^

    Vielen Dank an euch. 🙂



  • th3AddY schrieb:

    Ich deklariere die Methode als virtuell, da ich mehrere Kindklassen habe und nur dadurch Polymorphie und somit spätes Binden gewährleistet ist. (nach meinem Wissensstand)

    Es gibt genau einen Grund, weshalb virtuelle Funktionen erforderlich sind:

    Du hast einen Zeiger auf eine Basisklasse, der auf einem Objekt einer abgeleiteten Klasse verweist. Wenn Du zur Compiletime nicht weißt, welchen Typ das Objekt hat, auf das der Zeiger verweist und Du aber möchtest, das eine eventuell überladene Memberfunktion richtig aufgerufen wird, dann und nur dann mußt Du die Memberfunktion virtuel deklarieren.

    In allen Fällen, wo der Compiler schon zur Übersetzungszeit weiß, um was für ein Objekt es sich handelt, ist es nicht erforderlich und nur Zeit- und Speicherverschwendung.

    Ach ja: Mit Polymorphie hat das auch nichts zu tun.

    mfg Martin



  • mgaeckler schrieb:

    Ach ja: Mit Polymorphie hat das auch nichts zu tun.

    Das nehme ich zurück. Da hab' ich was verwechselt. 😞

    mfg Martin



  • mgaeckler schrieb:

    Ach ja: Mit Polymorphie hat das auch nichts zu tun.

    Ach?



  • hustbaer schrieb:

    mgaeckler schrieb:

    Ach ja: Mit Polymorphie hat das auch nichts zu tun.

    Ach?

    lern lesen


Anmelden zum Antworten