Grundlagenfrage Vererbung und Überschreiben



  • Kann man also sowas machen:
    in BasisDoc:

    virtual CBasisSet& GetDaten();
    

    in KundenDoc:

    virtual CKundenSet& GetDaten();
    

    in FirmenDoc:

    virtual CFirmenSet& GetDaten();
    

    und der nimmt dann immer die Funktion der abgeleiteten Klasse?
    Die Druckfunktion in der Basisklasse ist nämlich momentan nur ein Dummy, der später mal so aussehen wird:

    virtual void Drucke() = 0;
    


  • Ja. Der Rückgabewert gehört nicht zur Signatur einer Funktion. Desweiteren werden virtuelle Funktionen immer nach dem dynamischen Typ aufgelöst.



  • Cool, dann werde ich das Morgen mal umbauen. 👍
    Danke! 🙂



  • Es geht nicht. 😞
    In BasisDoc.h

    virtual CBasisSet& GetDaten() = 0;
    

    In KundenDoc.h

    CKundenSet& GetDaten();
    
    error C2555: 'CKundenDoc' von 'CKundenDoc::GetDaten': Neue Version der virtuellen Funktion unterscheidet sich von 'CBasisDoc::GetDaten' 
    nur hinsichtlich des Ergebnistyps oder der Aufrufkonvention
    

    Naja, und dann noch die üblichen Folgefehler... 🙄

    error C2259: "CKundenDoc" : Instanz von abstrakter Klasse kann auf Grund nachfolgender Elemente nicht erstellt werden:
    warning C4259: 'class CBasisSet &__thiscall CBasisDoc::GetDaten(void)' : Rein virtuelle Funktion wurde nicht definiert
    

    Geht das vielleicht nur mit Zeigern? Dann hätte ich viel umzubauen. 😞



  • estartu schrieb:

    Kann man also sowas machen:
    in BasisDoc:

    virtual CBasisSet& GetDaten();
    

    in KundenDoc:

    virtual CKundenSet& GetDaten();
    

    in FirmenDoc:

    virtual CFirmenSet& GetDaten();
    

    [/cpp]

    Das sollte AFAIK nicht gehen dürfen. Die virtuellen Methoden müssen beim überschreieben in den abgeleiteten Klassen exakt so aussehen wie in der Basisklasse ...

    Edit: Beachte camper's Post 😉



  • Freak_Coder schrieb:

    Das sollte AFAIK nicht gehen dürfen. Die virtuellen Methoden müssen beim überschreieben in den abgeleiteten Klassen exakt so aussehen wie in der Basisklasse ...

    Hatte Michael nicht gesagt, dass das geht? Oder hab ich da nur was rausgelesen, was ich lesen wollte? 😕

    Edit: Beachte camper's Post 😉

    Den da? http://www.c-plusplus.net/forum/viewtopic-var-t-is-151830.html
    Da hab ich den Zusammenhang noch nicht erkannt, aber ich denk nochmal drüber nach.

    Eventuell mache ich jetzt einfach eine GetBasisSet. Die heißt anders und dann sollte es gehen. 🙄



  • Oh sorry. Ich meinte den von Jester nicht camper. Die erste Antwort auf deinen Thread 🙂



  • Hallo,
    damit das funktioniert, muss dein Compiler "covariante Rückgabetypen" unterstützen. Der Rückgabetyp einer virtuellen Methode kann sich genau dann von der einer Basisklassenversion unterscheiden, wenn er spezieller ist, als der der Basisklasse.

    Bsp:

    class X {
    public:
    	virtual X& foo() = 0;
    };
    
    class Y : public X {
    public:
    	virtual Y& foo();
    };
    
    class Z : public Y {
    public:
    	virtual Z& foo();
    };
    

    Das ist völlig legal, für ältere Compiler wie z.B. den VC 6.0 allerdings nicht verdaubar.


  • Mod

    und dann gibt es noch eine denkschule, die der ansicht ist, dass virtuelle funktionen niemals public sein sollten.

    class X {
    public:
        X& foo() { return foo_impl(); }
    protected:
        virtual X& foo_impl() = 0;
    };
    
    class Y : public X {
    public:
        Y& foo() { return static_cast<Y&>(foo_impl()); }
    protected:
        virtual X& foo_impl();
    };
    
    class Z : public Y {
    public:
        Z& foo() { return static_cast<Z&>(foo_impl()); }
    protected:
        virtual X& foo_impl();
    };
    

    und schon sind wir nicht mehr auf compilerunterstützung für kovariante returntypen angewiesen. tatsächlich können wir sogar noch mahr tun. compilergestützte kovarianz beschränkt sich ja auf referenzen und pointer. wir könnten hier z.b. auch ohne weiteres smart pointer einsetzen (sofern sie untereinander konvertierbar sind).



  • camper schrieb:

    class X {
    public:
        X& foo() { return foo_impl(); }
    protected:
        virtual X& foo_impl() = 0;
    };
    
    class Y : public X {
    public:
        Y& foo() { return static_cast<Y&>(foo_impl()); }
    protected:
        virtual X& foo_impl();
    };
    
    class Z : public Y {
    public:
        Z& foo() { return static_cast<Z&>(foo_impl()); }
    protected:
        virtual X& foo_impl();
    };
    

    *STAUN* 😮 *FINDSCHÖN*



  • Freak_Coder schrieb:

    *STAUN* 😮 *FINDSCHÖN*

    In C++ Kreisen firmiert diese Denkschule unter dem Begriff "non-virtual interface idiom" (bzw. pattern) kurz NVI. Gut erklärt wird NVI z.B. in Sutters und Alexandrescus "C++ Coding Standards".



  • HumeSikkins schrieb:

    Das ist völlig legal, für ältere Compiler wie z.B. den VC 6.0 allerdings nicht verdaubar.

    Okay, da war der Haken... 😞

    Das mit der GetBasisSet funktioniert aber prima. 🙂
    Über das Beispiel eben von camper muss ich wohl nochmal in Ruhe nachdenken.
    Bei so arg theoretischen Sachen habe ich irgendwie Verständnisschwierigkeiten.


Anmelden zum Antworten