C++ “virtuelles” Schlüsselwort für Funktionen in abgeleiteten Klassen. Ist es nötig?

Lesezeit: 5 Minuten

C virtuelles Schlusselwort fur Funktionen in abgeleiteten Klassen Ist es
Anarki

Mit der unten angegebenen Strukturdefinition …

struct A {
    virtual void hello() = 0;
};

Ansatz Nr. 1:

struct B : public A {
    virtual void hello() { ... }
};

Ansatz Nr. 2:

struct B : public A {
    void hello() { ... }
};

Gibt es einen Unterschied zwischen diesen beiden Möglichkeiten, die Hallo-Funktion zu überschreiben?

  • In C++11 können Sie „void hello() override {}“ schreiben, um explizit zu erklären, dass Sie eine virtuelle Methode überschreiben. Der Compiler schlägt fehl, wenn keine virtuelle Basismethode vorhanden ist, und hat die gleiche Lesbarkeit wie das Platzieren von “virtual” in der untergeordneten Klasse.

    – Schattenjäger

    14. Februar 2013 um 4:20 Uhr

  • Tatsächlich ist es in C++11 von gcc in Ordnung, void hello() override {} in die abgeleitete Klasse zu schreiben, da die Basisklasse angegeben hat, dass die Methode hello() virtuell ist. Mit anderen Worten, die Verwendung des Wortes virtuell in der abgeleitet class ist für gcc/g++ sowieso nicht notwendig/obligatorisch. (Ich verwende gcc Version 4.9.2 auf einem RPi 3) Aber es ist eine gute Praxis, das Schlüsselwort virtual trotzdem in die Methode der abgeleiteten Klasse aufzunehmen.

    – Wille

    14. August 2017 um 7:11 Uhr


Sie sind genau gleich. Es gibt keinen Unterschied zwischen ihnen, außer dass der erste Ansatz mehr Tipparbeit erfordert und potenziell klarer ist.

  • Das stimmt, aber das Mozilla C++ Portabilitätshandbuch empfiehlt, immer virtual zu verwenden, da “einige Compiler” Warnungen ausgeben, wenn Sie dies nicht tun. Schade, dass sie keine Beispiele für solche Compiler erwähnen.

    – Sergei Tachenov

    4. Februar 2011 um 7:07 Uhr


  • Ich würde auch hinzufügen, dass das explizite Markieren als virtuell Sie daran erinnert, den Destruktor ebenfalls virtuell zu machen.

    – lfalin

    23. Juli 2014 um 19:34 Uhr

  • Nur um zu erwähnen, dasselbe gilt für den virtuellen Destruktor

    – Atul

    21. Juni 2015 um 23:57 Uhr

  • @SergeyTachenov laut Clifford‘s Kommentar zu seiner eigenen Antwort, ein Beispiel für solche Compiler ist armcc.

    – Ruslan

    6. Dezember 2015 um 7:40 Uhr


  • @Rasmi, Der neue Portabilitätsleitfaden ist daaber jetzt empfiehlt es sich, die zu verwenden override Stichwort.

    – Sergei Tachenov

    14. September 2016 um 18:36 Uhr

Die ‘Virtualität’ einer Funktion wird implizit weitergegeben, jedoch generiert mindestens ein von mir verwendeter Compiler eine Warnung, wenn die virtual Das Schlüsselwort wird nicht explizit verwendet, daher möchten Sie es vielleicht nur verwenden, um den Compiler ruhig zu halten.

Aus rein stilistischer Sicht, einschließlich der virtual Das Schlüsselwort „bewirbt“ den Benutzer eindeutig mit der Tatsache, dass es sich um eine virtuelle Funktion handelt. Dies wird für jeden wichtig sein, der B weiter unterklassifiziert, ohne die Definition von A überprüfen zu müssen. Für tiefe Klassenhierarchien wird dies besonders wichtig.

  • @James: armcc (ARM-Compiler für ARM-Geräte)

    – Clifford

    4. Februar 2011 um 18:48 Uhr

1646929811 840 C virtuelles Schlusselwort fur Funktionen in abgeleiteten Klassen Ist es
R Sahu

Die virtual Das Schlüsselwort ist in der abgeleiteten Klasse nicht erforderlich. Hier ist die unterstützende Dokumentation aus dem C++ Draft Standard (N3337) (Hervorhebung von mir):

10.3 Virtuelle Funktionen

2 Wenn eine virtuelle Mitgliedsfunktion vf wird in einer Klasse deklariert Base und in einer klasse Derivedabgeleitet direkt oder indirekt von Baseeine Mitgliedsfunktion vf mit demselben Namen, Parametertypliste (8.3.5), CV-Qualifikation und Ref-Qualifizierer (oder Fehlen derselben) wie Base::vf ist dann deklariert Derived::vf ist auch virtuell (ob es so deklariert ist oder nicht) und es überschreibt Base::vf.

  • Dies ist bei weitem die beste Antwort hier.

    – Fantastischer Herr Fuchs

    31. August 2018 um 7:18 Uhr

1646929812 889 C virtuelles Schlusselwort fur Funktionen in abgeleiteten Klassen Ist es
Colin D. Bennett

Nein, die virtual Schlüsselwort für virtuelle Funktionsüberschreibungen abgeleiteter Klassen ist nicht erforderlich. Aber es ist erwähnenswert, eine damit verbundene Falle zu erwähnen: ein Versäumnis, eine virtuelle Funktion zu überschreiben.

Die Fehler beim Überschreiben tritt auf, wenn Sie beabsichtigen, eine virtuelle Funktion in einer abgeleiteten Klasse zu überschreiben, aber einen Fehler in der Signatur machen, sodass sie eine neue und andere virtuelle Funktion deklariert. Diese Funktion kann eine sein Überlast der Basisklassenfunktion, oder sie kann sich im Namen unterscheiden. Ob Sie die verwenden oder nicht virtual Schlüsselwort in der Funktionsdeklaration der abgeleiteten Klasse verwenden, könnte der Compiler nicht erkennen, dass Sie beabsichtigten, eine Funktion aus einer Basisklasse zu überschreiben.

Dieser Fallstrick wird jedoch glücklicherweise von C++11 angegangen explizite Überschreibung Sprachfunktion, die es dem Quellcode ermöglicht, klar anzugeben, dass eine Elementfunktion eine Basisklassenfunktion überschreiben soll:

struct Base {
    virtual void some_func(float);
};

struct Derived : Base {
    virtual void some_func(int) override; // ill-formed - doesn't override a base class method
};

Der Compiler gibt einen Kompilierzeitfehler aus und der Programmierfehler ist sofort offensichtlich (vielleicht hätte die Funktion in Derived eine float als Argument).

Beziehen auf WP:C++11.

Das Hinzufügen des Schlüsselworts „virtuell“ ist eine bewährte Vorgehensweise, da es die Lesbarkeit verbessert , aber es ist nicht erforderlich. Funktionen, die in der Basisklasse als virtuell deklariert wurden und in den abgeleiteten Klassen dieselbe Signatur aufweisen, werden standardmäßig als „virtuell“ betrachtet.

1646929813 766 C virtuelles Schlusselwort fur Funktionen in abgeleiteten Klassen Ist es
Harfner

Es gibt keinen Unterschied für den Compiler, wenn Sie die schreiben virtual in der abgeleiteten Klasse oder lassen Sie es weg.

Aber Sie müssen sich die Basisklasse ansehen, um diese Informationen zu erhalten. Daher würde ich empfehlen, die hinzuzufügen virtual Schlüsselwort auch in der abgeleiteten Klasse, wenn Sie dem Menschen zeigen möchten, dass diese Funktion virtuell ist.

C virtuelles Schlusselwort fur Funktionen in abgeleiteten Klassen Ist es
Galaxis

Die virtual Schlüsselwort sollte zu Funktionen einer Basisklasse hinzugefügt werden, um sie überschreibbar zu machen. In deinem Beispiel struct A ist die Basisklasse. virtual bedeutet nichts für die Verwendung dieser Funktionen in einer abgeleiteten Klasse. Wenn Sie jedoch möchten, dass Ihre abgeleitete Klasse selbst eine Basisklasse ist, und Sie möchten, dass diese Funktion überschrieben werden kann, müssen Sie die virtual dort.

struct B : public A {
    virtual void hello() { ... }
};

struct C : public B {
    void hello() { ... }
};

Hier C erbt von Bdamit B ist nicht die Basisklasse (es ist auch eine abgeleitete Klasse) und C ist die abgeleitete Klasse. Das Vererbungsdiagramm sieht folgendermaßen aus:

A
^
|
B
^
|
C

Also solltest du die setzen virtual vor Funktionen innerhalb potenzieller Basisklassen, die Kinder haben können. virtual ermöglicht Ihren Kindern, Ihre Funktionen zu überschreiben. Es ist nichts falsch daran, das zu setzen virtual vor Funktionen innerhalb der abgeleiteten Klassen, ist aber nicht erforderlich. Es wird jedoch empfohlen, denn wenn jemand von Ihrer abgeleiteten Klasse erben möchte, wäre er nicht erfreut darüber, dass das Überschreiben der Methode nicht wie erwartet funktioniert.

Also setzen virtual vor Funktionen in allen an der Vererbung beteiligten Klassen, es sei denn, Sie wissen sicher, dass die Klasse keine Kinder haben wird, die die Funktionen der Basisklasse überschreiben müssten. Es ist eine gute Praxis.

988450cookie-checkC++ “virtuelles” Schlüsselwort für Funktionen in abgeleiteten Klassen. Ist es nötig?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy