Sinnsuche in Vererbung ?



  • Bingo ! Danke !
    Jetzt geht es ohne virtual nicht mehr.

    Verändert override noch zusätzlich etwas oder ist das für den compiler nur von Bedeutung ?

    Transportmittel : Mittel zur Fortbewegung von Gütern,Objekten,Personen...
    Auto : Mittel zur Fortbewegung vonPersonen...
    Transportmittel : Mittel zur Fortbewegung von Gütern,Objekten,Personen...
    Transportmittel : Mittel zur Fortbewegung von Gütern,Objekten,Personen...
    
    class  Transportmittel{
    public:
    	void /*virtual*/ definiere();
    };
    class Auto: public Transportmittel {
    public:
    	void definiere(); //override;
    };
    
    //cpp file: 
    void Transportmittel::definiere(){
    	cout<<"Transportmittel : Mittel zur Fortbewegung von Gütern,Objekten,Personen..."<<endl;
    	}
    
    void Auto::definiere(){
    	cout<<"Auto : Mittel zur Fortbewegung vonPersonen..."<<endl; 
    	} 
    int main(){
    Transportmittel blue;
    Auto green;
    blue.definiere();
    green.definiere();
    green.Transportmittel::definiere();
    
    Auto a; 
    Transportmittel* tm = &a; 
    tm->definiere(); 
    return 0;
    }
    


  • Wenn eine Funktion in der Basis virtual ist, kann das in der abgeleiteten Klasse nicht mehr geändert werden. Virtual ist hier technisch überflüssig. Es wird aber oft dennoch verwendet, um beim Lesen des Codes der abgeleiteten Klasse an die Tatsache zu erinnern. Wird virtual in der Basis entfernt, bleibt dies möglicherweise zunächst unbemerkt. Verwendet man in der abgeleiteten Klasse dagegen override, gäbe es dabei eine Fehlermeldung des Compilers.



  • Danke! , habs verstanden für den Anfang.
    (Die Frage stellt sich ja auch, wenn man merkt, dass die Funktion in der Basisklasse nicht entfernbar ist. Also tatsächlich überschreibbar aus der
    Kindklasse, was auch wieder Sinn ergibt...- egal ob override oder nicht, die
    Kindklasse sollte ja nicht die Dinge der Quelle zerstören können, da das ganze
    auch mit Pointern ablaueft...)
    Aber die Antwort macht Sinn.

    Transportmittel* tm = &a; 
    tm->definiere();
    tm->Transportmittel::definiere();
    
    Transportmittel : Mittel zur Fortbewegung von Gütern,Objekten,Personen...
    

    aus der Kindklasse kann man logischerweise nicht die Funktion der Quellklasse
    auslöschen. ("...override ist technisch überflüssig ... " )



  • override schützt auch von Schreibfehlern, beim Überschreiben von Funktionen in Unterklassen.

    class Auto: public Transportmittel {
    public:
        void Definiere(); //ohne "override" ist das eine neue Funktion
    };
    

    Edit:

    Die Funktion "definiere" wurde hier "versehentlich" falsch geschrieben (Anfangsbuchstabe ist hier "D" anstatt "d"). Mit dem Schlüsselwort "override" würde der Compiler an dieser Stelle einen Fehler melden.



  • Danke



  • temi schrieb:

    void Definiere(); //ohne "override" ist das eine neue Funktion
    

    Du meinst wohl eher:
    ohne "override" weiß man nichts genaues, ohne die Elternklasse zu kennen. Es könnte eine neue Funktion sein, es könnte eine virtuelle Funktion sein...
    Mit override ist sichergestellt, dass es irgendwo in einer der Elternklassen ein virtual void Definiere(); gibt.



  • wob schrieb:

    Du meinst wohl eher:
    ohne "override" weiß man nichts genaues, ohne die Elternklasse zu kennen. Es könnte eine neue Funktion sein, es könnte eine virtuelle Funktion sein...
    Mit override ist sichergestellt, dass es irgendwo in einer der Elternklassen ein virtual void Definiere(); gibt.

    Eigentlich meinte ich schon, was ich geschrieben habe.

    Ohne override erhält die Unterklasse eine neue Funktion mit dem Namen "Definiere". Die in der Basisklasse vorhandene virtuelle Funktion "definiere" wird nicht überschrieben. Mit override erhält man eine Fehlermeldung des Compilers, dass man überschreiben möchte, aber es nicht tut.

    Oder verstehe ich dich falsch?



  • temi schrieb:

    Eigentlich meinte ich schon, was ich geschrieben habe.

    Ohne override erhält die Unterklasse eine neue Funktion mit dem Namen "Definiere". Die in der Basisklasse vorhandene virtuelle Funktion "definiere" wird nicht überschrieben.

    Doch, sie wird auch ohne override überschrieben.

    Das kann man ja leicht testen:

    struct A { 
      virtual void x(){cout<<"Ax\n";}
    };
    struct B : public A {
      void x(){cout<<"Bx\n";}
    };
    int main() {
      A* a = new B();
      a->x();
    }
    

    Es wird hier "Bx" ausgegeben. Auch ohne override. Override macht nur ein Programm ungültig, wenn nicht überschrieben wird. Wenn du aus deinem Programm alle overrides (die an Funktonssignaturen, nicht mögliche Variablen mit demselben Namen) löscht, wird es unverändert weiter funktionieren. Genau wie "final" gibt es "override" auch erst seit C++11.



  • Und jetzt reden wir alle aneinander vorbei.



  • blurbs schrieb:

    Und jetzt reden wir alle aneinander vorbei.

    😃 Scheint so.

    wob: Bitte beachte das die Funktion in der Basisklasse "definiere" (kleines "d") heißt und in der "versehentlich" falsch geschriebenen Funktion in der Unterklasse "Definiere" (großes "D"). Das sind zwei unterschiedliche Funktionen.

    override schützt auch von Schreibfehlern, beim Überschreiben von Funktionen in Unterklassen.



  • temi:
    bitte beachte:

    wob schrieb:

    Du meinst wohl eher:
    ohne "override" weiß man nichts genaues, ohne die Elternklasse zu kennen. Es könnte eine neue Funktion sein, es könnte eine virtuelle Funktion sein...
    Mit override ist sichergestellt, dass es irgendwo in einer der Elternklassen ein virtual void Definiere(); gibt.



  • Ich bin froh, dass ich weiß, was ich gemeint habe. Anderen, die meinen, das ich etwas anderes meinte, sei es gegönnt.



  • Alle wissen, was Du gemeint hast, aber Du hast iwie ignoriert (oder nicht verstanden?), was wob gemeint hat. 😉



  • Ich muss als allererstes sagen, dass ich das kleine/große d/D nicht erkannt hatte. Sozusagen gleich mal den Nutzen von override in der Praxis bestätigt.

    Dennoch halte ich die den Kommentar von Temi
    //ohne "override" ist das eine neue Funktion
    für gefährlich/irreführend, weil er suggeriert, dass man hier durch Weglassen von override ein Programm ändern würde. Ein Kommentar wie

    // mit "override" gibt es einen Compile-Fehler,
    // ohne override wird nicht definiere überschrieben, sondern
    // die neue Funktion Definiere erzeugt
    

    wäre klar gewesen.

    Man sagt ja auch nicht:
    int main() buh! {} // ohne "buh!" wird die Funktion 'main' erstellt
    Ich ging implizit davon aus, dass das Programm auch vor dem Weglassen nicht ill-formed sein sollte (und man sich hier im Forum sowas wie d/D automatisch korrigiert).

    Dann ist jetzt auch hoffentlich klar, was ich gemeint habe.



  • wob schrieb:

    Dennoch halte ich die den Kommentar von Temi
    //ohne "override" ist das eine neue Funktion
    für gefährlich/irreführend, weil er suggeriert, dass man hier durch Weglassen von override ein Programm ändern würde. Ein Kommentar wie

    // mit "override" gibt es einen Compile-Fehler,
    // ohne override wird nicht definiere überschrieben, sondern
    // die neue Funktion Definiere erzeugt
    

    wäre klar gewesen.

    100% Zustimmung. Der Kommentar war, zumindest ohne zusätzliche Erläuterung, irreführend (und auch nicht im dem Sinn gemeint, wie von wob beschrieben).

    Danke für die Korrektur.



  • wob schrieb:

    Ich muss als allererstes sagen, dass ich das kleine/große d/D nicht erkannt hatte. Sozusagen gleich mal den Nutzen von override in der Praxis bestätigt.

    Das ist ja gerade der Witz dabei. Um das überhaupt erkennen zu können, muss man ja zwingend die Elternklasse kennen. Du hast aber ja wie oben schon mal zitiert geschrieben:

    wob schrieb:

    ohne "override" weiß man nichts genaues, ohne die Elternklasse zu kennen. Es könnte eine neue Funktion sein, es könnte eine virtuelle Funktion sein...


Anmelden zum Antworten