2013-08-07 6 views
12

Ich verstehe, dass C++ Laufzeitpolymorphismus durch virtuelle Funktionen implementiert und dass virtuelles Schlüsselwort vererbt wird, aber ich sehe keine Verwendung von virtuellen Schlüsselwort in abgeleiteten Klasse.Verwendung von virtuellen Schlüsselwörtern in C++

z.B. Im unteren Fall, selbst wenn Sie das virtuelle Schlüsselwort in der abgeleiteten Klasse gelöscht haben, geht der Aufruf von ptr-> method() zu abgeleiteten :: method. Also, was dieses virtuelle Schlüsselwort in abgeleiteten Klasse tut?

#include<iostream> 

using namespace std; 

class base 
{ 
public: 
    virtual void method() 
    { 
     std::cout << std::endl << "BASE" << std::endl; 
    } 
}; 

class derived: public base 
{ 
public: 
    virtual void method() 
    { 
     std::cout << std::endl << "DERIVED" << std::endl; 
    } 
}; 

int main() 
{ 
    base* ptr = new derived(); 
    ptr->method(); 
    return 9; 
} 
+0

Wie Sie gesehen haben, ist es redundant. – BoBTFish

+0

@ Nbr44 würden Sie keine Antwort von diesem Kommentar machen – triclosan

+0

'virtual' ist in der abgeleiteten Klasse implizit beim Überschreiben einer virtuellen Funktion in der Basisklasse. C++ 11 führt auch das Schlüsselwort final ein, das verhindert, dass weitere abgeleitete Klassen die virtuelle Funktion erneut implementieren. – dunc123

Antwort

6

Nichts. Nur um Sie daran zu erinnern, welche Funktionen virtuell sind oder nicht.

8

virtual ist nur in der Basisklasse-Deklaration erforderlich. Es ist optional in der abgeleiteten Klasse (den abgeleiteten Klassen) und dient meistens als Erinnerung in diesen Fällen.

C++ 11 führt override ein, um die Dinge noch expliziter zu machen: Es markiert explizit eine Methode in einer abgeleiteten Klasse als eine Überschreibung einer virtual Methode einer Basisklasse.

21

Wenn die Methode der abgeleiteten Klasse mit einer virtuellen Methode einer der Basisklassen nach Name und Signatur übereinstimmt und die übereinstimmende Methode virtuell ist, wird die Methode einer abgeleiteten Klasse ebenfalls virtuell. Daher ist es technisch nicht notwendig, solche Methoden in abgeleiteten Klassen als «virtuell» zu markieren. Vor C++ 11 war es jedoch eine gute Übung, nur weil es ein guter Hinweis für diejenigen ist, die den Code lesen (es könnte schwierig sein, alle virtuellen Funktionen der Basisklasse (n) im Kopf zu behalten).

Beginnend mit C++ 11 gibt es in den abgeleiteten Klassen zwei zusätzliche Schlüsselwörter, die sowohl die Lesbarkeit als auch die Robustheit des Codes verbessern. Sie sind «override» und «final». Zum Beispiel stellt das Setzen von «override» in einer Methode einer abgeleiteten Klasse sicher, dass eine entsprechende Methode einer Basisklasse tatsächlich virtuell ist. Das Schlüsselwort «final» bewirkt dasselbe und verhindert, dass die Methode weiter überschrieben wird.

Ich schrieb darüber auch mit mehr Real-Welt-Logik und Code-Beispiele in meinem Blog, here.

Ich hoffe, es hilft. Viel Glück!

+1

Ich habe Ihren Blogpost gemocht, und ich könnte beginnen, override/final in der Tat zu verwenden. – hauron

+0

Der 'final' * special identifier * tut nicht das gleiche wie' override' plus ..., es verhindert nur das Überschreiben in abgeleiteten Typen. Während es wenig Sinn macht, eine virtuelle Funktion 'final' zu erstellen, wenn sie keine andere Funktion überschreibt (warum wird sie dann virtuell gemacht?), Wird der Compiler nicht überprüfen, dass sie irgendetwas überschreibt, dafür müssen Sie' final' und Überschreiben. Das heißt, "override" erfordert, dass es eine Überschreibung in der Basis gibt, "final" impliziert, dass es keine Überschreibungen in abgeleiteten Typen geben kann. Einer schaut auf, der andere runter. Basistest in [ideone] (http://ideone.com/2xVsFE) –

+0

@ DavidRodríguez-dribeas: David, tut es, außer wenn Sie auch diese Funktion als «virtuell» markieren. Zum Beispiel, wenn Sie eine Funktion nur als «final» markiert haben und es keine virtuelle Basis dafür gibt, erhalten Sie einen Fehler wie «nur virtuelle Memberfunktionen können als 'final' markiert werden» –

0

Das virtuelle Schlüsselwort ist in der Laufwerksklasse optional, da Sie nach der Regel eine Klasse mit der Basisklasse steuern, die eine virtuelle Funktion hat, und wenn Sie die virtuelle Funktion im Laufwerkklassencompiler implizit zuweisen, zusammen mit der Funktion ein virtuelles Schlüsselwort zuweisen. Sie müssen also das virtuelle Schlüsselwort nicht explizit zuweisen. Dieses Schlüsselwort ist jedoch während der Multilevel-Vererbung erforderlich.

Beispiel:

In Ihrem Code fügen wir diesen Code.

class derived: public base { 
    public: 
     virtual void method() { // In this line virtual keyword is optional. 
       std::cout << std::endl << "DERIVED :: method function" << std::endl; 
     } 

     virtual void display() { 
       std::cout << std::endl << "DERIVED :: display function" << std::endl; 
     } 
    }; 

    class deriveChild: public derived { 
     public: 
      void method() { 
       std::cout << std::endl << "DERIVECHILD :: method" << std::endl; 
      } 

     void display() { 
       std::cout << std::endl << "DERIVECHILD:: display" << std::endl; 
      } 
    }; 

In der Haupt(), wenn Sie unter Code verwenden, gibt es Ihnen unterschiedliche Ausgabe.

Wenn Sie nun display() der Klasse derivateChild verwenden möchten, verwenden Sie diesen Code.

derived *ptr = new deriveChild(); 
    ptr->method(); // Compile and Execute 
    ptr->display(); // Compile and Execute 
0

Implizit virtuelle Methoden in abgeleiteten Klassen virtuell sind in abgeleiteten Klassen, keine Notwendigkeit, sie explizit definieren virtual.If Sie erklären wird es redundante Erklärung sein.

ptr->method(); 

Wenn der Compiler für die obige Aussage kam

-> Er wird versuchen, die obige Aussage, wie das Verfahren() Funktion ist virtuell zu lösen, Compiler die Lösung dieses Anrufs verschieben Zeit zu laufen.

-> Wenn Sie das Objekt der abgeleiteten Klasse zur Laufzeit erstellt haben, wird der Compiler jetzt wissen, dass diese Methode von der abgeleiteten Klasse ist.

Welchen zusätzlichen Wert hat dieses virtuelle Schlüsselwort in der abgeleiteten Klasse?

Betrachten Sie dieses Szenario gibt es eine weitere abgeleitete Klasse namens Derived2 inherting Form abgeleitet und es hat seine eigene virtuelle Methode.

class derived2: public derived 
{ 
public: 
    virtual void method() 
    { 
     std::cout << std::endl << "DERIVED2" << std::endl; 
    } 
}; 

Wenn Sie die Methode() in Haupt nennen wie unter

int main() 
{ 
    base* ptr = new derived2(); 
    ptr->method(); //derived2 class method() will get called 
    return 9; 
} 

Wenn die Methode() in Derived2 standardmäßig nicht virtuell ist, werden Sie teh abgeleitete Version der Methode aufrufen Ende() , den Vorteil des Laufzeitpolymorphismus zu verlieren.

Daher haben die Autoren von C++ hier eine wunderbare Arbeit geleistet, indem sie die virtuelle Schlüsselwortvererbung hierarchisch gemacht haben.