Aufruf polymorpher Funktionen aus Oberklasse heraus?



  • Hi,

    folgender Code hat mich stutzig gemacht:

    class Basis 
    {
    protected:
    virtual void polyfoo1() {}
    virtual void polyfoo2() {}
    virtual void polyfoo3() {}
    
    public:
    Basis() {polyfoo();}
    ~Basis() {polyfoo();}
    void Method() {polyfoo3();}
    };
    
    class Derived : public Basis
    {
    virtual void polyfoo1() {std::cout << "Call Foo1";}
    virtual void polyfoo1() {std::cout << "Call Foo2";}
    virtual void polyfoo1() {std::cout << "Call Foo3";}
    
    Derived() : Basis() {}
    ~Derived() {}
    }
    
    int main()
    {
    Derived x;
    x.Method();
    
    return 0;
    }
    

    Ausgabe ist Call Foo3. Ich kann auch nur polyfoo3 in der Basisklasse rein virtuell deklarieren. Ich weiß jetzt nicht, inwiefern der VC++ 2008 jetzt irgendwelche Vorstellungen hat oder das dem Standard entspricht. Falls es demselben entspricht, weiß ich nicht, wieso. Hat jemand vielleicht einen Link oder eine Erklärung für mich? 😕

    Viele Grüße



  • Da sind ja zig Abtippfehler drin. 🙄

    Ich weiß nicht genau, was Du testen wolltest. Es ist aber normal, dass wenn Du virtuelle Funktionen in einem Konstruktor oder Destruktor aufrufst, dass das dann nie Funktionen von irgendwelchen abgeleiteten Klassen sind. Das ist sogar Absicht. Denk mal über die Lebenszeit von Objektelementen einer abgeleiteten Klasse nach, dann kommst Du vielleicht selbst drauf, warum das Verhalten so gewollt ist.

    Gruß,
    SP



  • Kannst du das mal bitte ordentlich einrücken? So hättest du dir die cpp-Tags auch sparen können.

    Und Code:
    Es ist weder eine polyfoo() definiert, noch ein polyfoo[2,3] in Derived, stattdessen 3* polyfoo1()...

    Und virtuelle Funktionen im Konstruktor aufrufen ist ganz ganz böse, weil nicht das macht was du denkst!
    Derived x -> Zuerst wird die Basis initialisiert, also der Konstruktor Base() aufgerufen. Zu dem Zeitpunkt ist das Objekt aber garantiert noch kein Derived. Deshalb kann auch nicht die entsprechende Implementierung aufgerufen werden. Viel Spaß beim Debuggen.

    Und deshalb kommt im übrigen auch nicht
    Call Foo 3
    Call Foo 3
    was du wohl auch erwartest, als Ausgabe, sondern eben nur
    Call Foo 3

    Ci-AU



  • polyfoo3() (intuitive Korrektur Deiner Tippfehler mal vorausgesetzt) ist eine virtuelle Methode, also wird die Methode der Klasse des zugrunde liegenden Objektes aufgerufen und dieses ist halt Derived.
    Du solltest Dich zum Verständnis vielleicht mal näher mit dem this Pointer und der vtable beschäftigen. Das hat mich auch gehelft 😉



  • Eisflamme schrieb:

    ...

    Wenn ich dir noch einen Buchtip auf den Weg geben darf: "Effektiv C++ Programmieren" (3 Auflage; Addison Wesley Verlag; Scott Meyers) und bitte auch darauf achten das es die 3te, und keine Ältere Auflage ist. Dort sind unter anderem solche Dinge beschrieben.



  • Ja, beim vtable muss ich noch ein wenig Nachholarbeit leisten, das stimmt wohl. 🙂

    Die Tippfehler hatte ich eigentlich alle korrigiert, aber irgendwie schein ich's dann mim Einfügen verpeilt zu haben, sorry.

    Danke jedenfalls für die Antworten, habe mir das schon so gedacht, aber wollte es nochmal sicher haben (nicht, dass MVC++ einfach irgendwas macht und ich davon ausgehe, dass es Standard ist).

    Viele Grüße


Anmelden zum Antworten