Soweit ich weiß, die Einführung von override
Schlüsselworts in C ++ 11 nichts anderes als eine Überprüfung, um sicherzustellen, dass die implementierte Funktion die Funktion override
einer virtual
Funktion in der Basisklasse ist.
Ist es das?
Soweit ich weiß, die Einführung von override
Schlüsselworts in C ++ 11 nichts anderes als eine Überprüfung, um sicherzustellen, dass die implementierte Funktion die Funktion override
einer virtual
Funktion in der Basisklasse ist.
Ist es das?
Antworten:
Das ist in der Tat die Idee. Der Punkt ist, dass Sie explizit angeben, was Sie meinen, damit ein ansonsten stiller Fehler diagnostiziert werden kann:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
Der obige Code wird kompiliert, ist aber möglicherweise nicht das, was Sie gemeint haben (beachten Sie das Fehlen const
). Wenn Sie stattdessen sagten, virtual int foo() override
würden Sie einen Compilerfehler erhalten, dass Ihre Funktion tatsächlich nichts überschreibt.
override
Funktion dies "behebt"; Sie müssen daran denken, es zu verwenden, genau wie Sie daran gedacht haben sollten, das zu schreiben const
;)
explicit
Klassendefinitionen es nicht in C ++ 11 geschafft haben. Huh.
explicit
Klassendefinition tun? Ich habe noch nie davon gehört.
override
wenn man es vorhat) ist jedoch wahrscheinlicher als das Erinnern an Eckfälle, dh es gibt keine Allgemeingültigkeit beim Kopieren von Funktionen verschiedener Prototypen, nur Unregelmäßigkeiten wie Fehlen const
oder Schreiben char
statt int
usw.
override
Spezifizierers wird in dieser Antwort erwähnt , die eher futuristisch als unmittelbar ist. Die Antwort legt nahe, dass Sie override
die virtual
Methode beibehalten. Wenn man in Zukunft fälschlicherweise die Signatur ändert, setzt ihre Nützlichkeit ein.
Wikipedia-Zitat:
Die spezielle ID zum Überschreiben bedeutet, dass der Compiler die Basisklasse (n) überprüft, um festzustellen, ob es eine virtuelle Funktion mit genau dieser Signatur gibt. Wenn dies nicht der Fall ist, tritt ein Fehler beim Compiler auf.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Bearbeiten (versucht die Antwort ein wenig zu verbessern):
Das Deklarieren einer Methode als "Überschreiben" bedeutet, dass diese Methode eine (virtuelle) Methode für die Basisklasse umschreiben soll . Die überschreibende Methode muss dieselbe Signatur haben (zumindest für die Eingabeparameter) wie die Methode, die neu geschrieben werden soll.
Warum ist das notwendig? Nun, die folgenden zwei häufigen Fehlerfälle werden verhindert:
man tippt einen Typ in der neuen Methode falsch ein. Der Compiler, der nicht weiß, dass er beabsichtigt, eine vorherige Methode zu schreiben, fügt sie der Klasse einfach als neue Methode hinzu. Das Problem ist, dass die alte Methode noch vorhanden ist, die neue wird nur als Überladung hinzugefügt. In diesem Fall funktionieren alle Aufrufe der alten Methode wie zuvor, ohne dass sich das Verhalten ändert (was der eigentliche Zweck des Umschreibens gewesen wäre).
man vergisst, die Methode in der Oberklasse als "virtuell" zu deklarieren, versucht aber dennoch, sie in einer Unterklasse neu zu schreiben. Obwohl dies anscheinend akzeptiert wird, ist das Verhalten nicht genau wie beabsichtigt: Die Methode ist nicht virtuell, sodass der Zugriff über Zeiger auf die Oberklasse den Aufruf der alten Methode (Oberklasse ') anstelle der neuen Methode (Unterklasse') beendet.
Das Hinzufügen von "Überschreiben" macht dies eindeutig deutlich: Dadurch teilt man dem Compiler mit, dass drei Dinge erwartet werden:
Wenn einer dieser Punkte falsch ist, wird ein Fehler gemeldet.
* Hinweis: Der Ausgabeparameter ist manchmal von einem anderen, aber verwandten Typ. Lesen Sie bei Interesse mehr über kovariante und kontravariante Transformationen.
Gefunden " Überschreiben " ist nützlich, wenn jemand die Signatur der virtuellen Methode der Basisklasse aktualisiert hat, z. B. einen optionalen Parameter hinzugefügt hat, aber vergessen hat, die Signatur der abgeleiteten Klassenmethode 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 herauszufinden.
override
eine gute Möglichkeit ist, solche Probleme zu entdecken, sollte auch eine gute Abdeckung durch Unit-Tests hilfreich sein.
Ja, das ist so. Es ist eine Überprüfung, um sicherzustellen, dass man keine Überschreibung versucht und sie durch eine verpfuschte Signatur durcheinander bringt. Hier ist eine Wiki-Seite, die dies ausführlich erklärt und ein kurzes anschauliches Beispiel enthält:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
C ++ 17 Standardentwurf
Nachdem ich alle override
Treffer des C ++ 17 N4659-Standardentwurfs durchgesehen habe, kann ich nur auf den override
Bezeichner verweisen :
5 Wenn eine virtuelle Funktion mit dem Virt-Specifier-Override markiert ist und eine Member-Funktion einer Basisklasse nicht überschreibt, ist das Programm fehlerhaft. [Beispiel:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- Beispiel beenden]
Daher denke ich, dass möglicherweise das Sprengen falscher Programme der einzige Effekt ist.