c++11 overriding functions



  • Hallo,

    ich bin gerade dabei den letzten teil meines alten C++ buches durchzuarbeiten. In dem teil zu 'overriding base functions' steht :

    'When you override a function, it must agree in return type and in signature with the function in the base class.'

    In Visual Studio 2013 scheint das nicht mehr der fall zu sein. Ich kann zum beispiel eine funktion :

    void base_class::move() const {}
    

    mit

    int derived_class::move(int x, int y) {}
    

    überschreiben!

    Hat sich da in der Zeit etwas verrändert oder verstehe ich da etwas falsch ?



  • Ist ein alter Sprachdefekt. Mach mal hier ein "override" hin:

    int derived_class::move(int x, int y) override {}
    

    Dann erklärt der Compiler dir hoffentlich, was hier passiert.



  • audacia schrieb:

    Ist ein alter Sprachdefekt. Mach mal hier ein "override" hin:

    int derived_class::move(int x, int y) override {}
    

    Dann erklärt der Compiler dir hoffentlich, was hier passiert.

    Hmm, 'override' scheint nur für virtuelle funktionen zu sein ?



  • Im prinzip erstelle ich doch eine neue funktion, wodurch die in der base class versteckt wird oder ? Wobei dieses 'verhalten' doch nur bei wirklichem überschreiben zu beobachten ist, eigentlich sollte da doch wenigstens eine Warnung kommen.



  • Du musst unterschieden zwischen verstecken und überschreiben:

    class parent
    {
    public:
        void method1(){}
    };
    
    class child:parent
    {
    public:
        void method1(){}
    };
    
    //...
    child objChild;
    parent* objParent = (parent*)&objChild;
    objParent->method1(); //Ruft die Methode aus parent auf, da die Methode nur versteckt wurde
    
    class parent
    {
        virtual void method1();
    };
    
    class child:parent
    {
        void method1();
    };
    
    //...
    child objChild;
    parent* objParent = (parent*)&objChild;
    objParent->method1(); //Ruft die Methode aus child auf, da die Methode überschrieben wurde
    


  • Das bedeutet dass wenn ich eine base class Funktion, welche nicht als virtual deklariert ist in irgendeiner weise in der derived class neu definiere werde ich in JEDEM Fall nur die base class Funktion verstecken ?

    'irgendeine weise' :

    zb.

    class parent
    {
     public:
     void method1(); //void, keine parameter, kein const
    }
    
    class child1 : public parent
    {
     public:
     void method1(); //genau gleich
    }
    
    class child2 : public parent
    {
     public:
     int method1(); //returns int
    }
    
    class child3 : public parent
    {
     public:
     void method1(int i); // hat einen parameter
    }
    
    class child2 : public parent
    {
     public:
     void method1() const; //const
    }
    

    Wenn ich es jetzt richtig verstanden habe findet hier nirgends 'overriding' statt sondern es wird lediglich die base class Funktion versteckt. Overriding ist also nur möglich bei virtuellen Funktionen.

    Wenn ich jetzt aber eine virtuelle Funktion habe und sie überschreibe, dann aber später bei der Nutzung keinen base pointer zu einem child objekt habe sondern ein ganz normales object vom typ child wie wirkt dann das virtual ?



  • Ceno schrieb:

    Das bedeutet dass wenn ich eine base class Funktion, welche nicht als virtual deklariert ist in irgendeiner weise in der derived class neu definiere werde ich in JEDEM Fall nur die base class Funktion verstecken ?

    Wenn eine Methode nicht virtual ist, kannst du sie auch nicht überschrieben. Ergo ja, du kannst sie nur verstecken.

    Ceno schrieb:

    Wenn ich jetzt aber eine virtuelle Funktion habe und sie überschreibe, dann aber später bei der Nutzung keinen base pointer zu einem child objekt habe sondern ein ganz normales object vom typ child wie wirkt dann das virtual ?

    Dann ändert es natürlich nichts. Du solltest nochmal nachlesen was genau Polymorphie bedeutet.
    Wenn du von einer Klasse ableitest und eine Methode überschreibst, kannst du die Klasse problemlos auf die Parentklasse casten. Und wenn die Methode der Parentklasse aufgerufen wird, dann wird stattdessen die Methode des Childs aufgerufen.
    Du kannst also z.B. mehrere Parent-Pointer haben, von denen sich jedes Objekt anders verhält weil es von einer abgeleiteten Klasse ist.



  • Okay das habe ich jetzt schon ganz gut verstanden aber könntest du nochmal :

    DarkShadow44 schrieb:

    Dann ändert es natürlich nichts

    genauer definieren ?

    class parent
    {
     public:
     virtual void foo() { cout << "parent" << endl; }
    }
    
    class child : public parent
    {
     public:
     void foo() { cout << "child" << endl; }
    }
    
    int main()
    {
     child derived;
     derived.foo();
    
     return 0;
    }
    

    Wie genau läuft das jetzt ? Wenn man

    parent * base = new child();
    

    hat ist mir klar was passiert, das ist ja der sinn von Polymorphie!



  • Ceno schrieb:

    Wie genau läuft das jetzt ?

    Das ruft natürlich die Methode des Childs auf, wie du auch einfach testen kannst.
    Mit oder ohne überschreiben, wenn du die Methode des Childs aufrufst wird auch genau die aufgerufen.
    Kann sein dass das Program einen Lookup in der "Virtual method table" macht, d.h. dynamisch nachschaut welche Funktion er jetzt aufrufen muss. Aber selbst wenn kommt ja nur die des Childs in Frage.



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • So weit ich weiß, wird in normalen Klassen nach Funktions-Überladungen nur in derselben Klasse gesucht, daher "sieht" der Compiler gar nicht ob es in einer Vaterklasse eine Methode mit demselben Namen gibt.



  • Nach ein paar stunden mit einem hex editor und einem debugger habe ich es jetzt endgültig verstanden! Danke für die Hilfe 🙂


Anmelden zum Antworten