2012-12-14 4 views

Antwort

183

Das ist in der Tat die Idee. Der Punkt ist, dass Sie explizit über das, was du meinst, so dass ein ansonsten stiller Fehler diagnostiziert werden kann:

struct Base 
{ 
    virtual int foo() const; 
}; 

struct Derived : Base 
{ 
    virtual int foo() // whoops! 
    { 
     // ... 
    } 
}; 

Der obige Code kompiliert, aber nicht das, was man (man beachte die fehlenden const) gemeint haben könnte. Wenn Sie stattdessen virtual int foo() override sagten, dann würden Sie einen Compiler-Fehler bekommen, dass Ihre Funktion tatsächlich nichts überschreibt.

+51

+1: Obwohl es leider ein bisschen ein Ablenkungsmanöver ist, wenn Leute vorschlagen, dass das neue "override" -Feature das behebt; Sie müssen daran denken, es zu benutzen, genau wie Sie sollten sich daran erinnern, die "const" zu schreiben;) –

+0

Ich habe gerade festgestellt, explizite 'Klassen-Definitionen haben es nicht in C++ 11. Huh. – aschepler

+1

@ascheppler Und was würde eine 'explizite' Klassendefinition tun? Davon habe ich noch nie gehört. –

23

Wikipedia Zitat:

Die Überschreibung spezielle Kennung bedeutet, dass der Compiler die Basisklasse überprüfen (es) um zu sehen, ob es eine virtuelle Funktion mit genau dieser Signatur gibt. Und wenn nicht, wird der Compiler fehlschlagen.

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

Edit (Versuch, ein bisschen die Antwort zu verbessern):

ein Verfahren als „überschreiben“ Deklarieren bedeutet, dass das Verfahren soll eine (virtuelle) Methode auf die neu zu schreiben Basisklasse. Die überschreibende Methode muss dieselbe Signatur (zumindest für die Eingabeparameter) haben wie die Methode, die neu geschrieben werden soll.

Warum ist das notwendig? Nun, die folgenden zwei häufigen Fehlerfälle werden verhindert:

  1. man vertippt einen Typ in der neuen Methode. Der Compiler, der nicht weiß, dass er eine frühere Methode schreiben möchte, fügt sie einfach als neue Methode zur Klasse hinzu. Das Problem ist, dass die alte Methode immer noch da ist, die neue wird nur als Überladung hinzugefügt. In diesem Fall funktionieren alle Aufrufe in Richtung der alten Methode genauso wie zuvor, ohne irgendeine Änderung im Verhalten (was der Zweck des Umschreibens gewesen wäre).

  2. man vergisst, die Methode in der Oberklasse als "virtuell" zu deklarieren, versucht aber immer noch, sie in eine Unterklasse zu schreiben. Während dies scheinbar akzeptiert wird, wird das Verhalten nicht genau so sein wie beabsichtigt: Die Methode ist nicht virtuell, so dass der Zugriff durch Zeiger auf die Oberklasse den Aufruf der alten (Oberklassen-) Methode anstelle der neuen (Unterklassen-) Methode beendet.

„überschreibt“ deutlich disambiguiert dies hinzu: Dadurch wird man die Compiler zu sagen, dass drei Dinge erwarten:

  1. es in der übergeordneten Klasse
  2. dies ein Verfahren, mit dem gleichen Namen Methode in der Oberklasse wird als "virtual" deklariert (das heißt, umgeschrieben werden soll)
  3. die Methode in der Oberklasse hat die gleiche (Eingabe *) Signatur wie die Methode in der Unterklasse (die Neuschreibmethode)

Wenn einer dieser Werte falsch ist, wird ein Fehler gemeldet.

* Hinweis: Der Ausgabeparameter ist manchmal von verschiedenen, aber verwandten Typ. Lesen Sie bei Interesse über kovariante und kontravariante Transformationen.

18

Gefunden "überschreiben" ist nützlich, wenn jemand Basisklasse virtuelle Methode Signatur wie Hinzufügen eines optionalen Parameters aktualisiert, aber vergessen, abgeleitete Klassenmethode Signatur zu aktualisieren. In diesem Fall sind die Methoden zwischen der Basis und der abgeleiteten Klasse keine polymorphe Beziehung mehr. Ohne die Override-Deklaration ist es schwierig, diese Art von Fehler zu finden.

+0

+1. Obwohl 'override' eine gute Möglichkeit ist, solche Probleme zu entdecken, sollte auch eine gute Testabdeckung helfen. –

+0

Genau deshalb bin ich so begeistert von diesem neuen Spezifizierer. Das einzige Problem ist, dass dieses Feature bereits angewendet werden muss, um Fehler zu verhindern, die durch Änderungen in Basisklassen verursacht werden. ;-) – Wolf