wake-up-neo.com

Ist das Schlüsselwort 'override' nur eine Prüfung auf eine überschriebene virtuelle Methode?

Soweit ich weiß, ist die Einführung des override-Schlüsselworts in C++ 11 nichts anderes als eine Überprüfung, um sicherzustellen, dass die implementierte Funktion der overrideing einer virtual-Funktion in der Basisklasse ist.

Ist es das?

190
aiao

Das ist in der Tat die Idee. Der Punkt ist, dass Sie explizit sagen, was Sie meinen, 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 wird kompiliert, ist aber nicht das, was Sie vielleicht gemeint haben (beachten Sie das fehlende const). Wenn Sie stattdessen virtual int foo() override sagten, würden Sie einen Compiler-Fehler erhalten, bei dem Ihre Funktion tatsächlich nichts überschreibt.

217
Kerrek SB

Wikipedia-Zitat:

Die spezielle Kennung zum Überschreiben bedeutet, dass der Compiler die Basisklasse (n) daraufhin überprüft, ob eine virtuelle Funktion mit dieser genauen Signatur vorhanden ist. Wenn dies nicht der Fall ist, wird der Compiler einen Fehler ausgeben.

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

Bearbeiten (Versuch, die Antwort etwas zu verbessern):

Das Deklarieren einer Methode als "Überschreiben" bedeutet, dass diese Methode ist beabsichtigt eine (virtuelle) Methode in die Basisklasse schreibt. Die überschreibende Methode muss (zumindest für die Eingabeparameter) dieselbe Signatur wie die Methode haben, die sie neu schreiben möchte.

Warum ist das nötig? Nun, die folgenden zwei häufigsten Fehlerfälle werden verhindert:

  1. man schreibt einen Typ in der neuen Methode falsch. Der Compiler, der nicht bekannt ist, 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 Methode 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).

  2. man vergisst, die Methode in der Superklasse als "virtuell" zu deklarieren, versucht jedoch immer noch, sie in einer Unterklasse neu zu schreiben. Während dies anscheinend akzeptiert wird, ist das Verhalten nicht genau wie beabsichtigt: Die Methode ist nicht virtuell. Der Zugriff über Zeiger auf die Superklasse beendet dann das Aufrufen der alten (Superklassen) -Methode anstelle der neuen (Unterklassenmethode).

Das Hinzufügen von "override" macht dies eindeutig klar: Dadurch wird dem Compiler mitgeteilt, dass drei Dinge erwartet werden:

  1. es gibt eine Methode mit dem gleichen Namen in der Oberklasse
  2. diese Methode in der Superklasse wird als "virtuell" deklariert (dh sie soll neu geschrieben werden).
  3. die Methode in der Oberklasse hat die gleiche (Eingabe *) Signatur wie die Methode in der Unterklasse (die Umschreibungsmethode).

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

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

30
user1284631

Found " override " ist hilfreich, wenn jemand die Signatur der virtuellen Basissystemmethode aktualisiert hat, z. B. das Hinzufügen eines optionalen Parameters, aber vergessen, die Signatur der abgeleiteten Klassenmethode zu aktualisieren. In diesem Fall sind die Methoden zwischen der Basis und der abgeleiteten Klasse keine polymorphen Beziehungen mehr. Ohne die Überschreibungsdeklaration ist es schwierig, diese Art von Fehler herauszufinden.

24
user3792211

Ja das ist so. Es ist eine Überprüfung, um sicherzustellen, dass man keine Überschreibung versucht und es durch eine misslungene Signatur durcheinander bringt. Hier ist eine Wiki-Seite, die dies ausführlich erklärt und ein kurzes illustratives Beispiel enthält:

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

5
RonaldBarzell

C++ 17-Standardentwurf

Nachdem ich alle override-Treffer im C++ 17 N4659-Standardentwurf durchgegangen bin, kann ich nur auf die override-Kennung verweisen:

5 Wenn eine virtuelle Funktion mit dem Virt-Specifier-Override markiert ist und keine Member-Funktion eines .__ überschreibt. Basisklasse ist das Programm schlecht geformt. [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
}

- Ende Beispiel]

ich denke also, dass möglicherweise falsche Programme gesprengt werden, eigentlich der einzige Effekt.