Ist es sinnvoll, eine Basisklassenfunktion sowohl als virtuell als auch als final zu markieren? [Duplikat]

7

In verschiedenen Erklärungen von C ++ 11% final Schlüsselwort, ich sehe Beispiele wie diese.

%Vor%

Ist das wirklich eine nützliche Verwendung von final ? Warum würden Sie eine virtuelle Funktion in einer Basisklasse deklarieren (was bedeutet, dass sie in abgeleiteten Klassen sinnvollerweise außer Kraft gesetzt werden kann) und dann sofort als final markieren (diese Implikation negieren)? Was ist der Nutzen von virtual void f() final ?

Ich kann den Wert der Markierung derived::f() final statt base::f() sehen. In diesem Fall hatte base::f() vermutlich einen guten designbasierten Grund dafür, warum f() virtuell sein sollte, und derived::f() hat separat einen guten designbasierten Grund dafür, warum keine weiter abgeleitete Klasse ihre Implementierung außer Kraft setzen sollte.

Wenn Sie die Funktion nicht polymorph überschreiben möchten, warum lassen Sie nicht einfach das virtuelle Schlüsselwort weg? Natürlich können abgeleitete Klassen die Funktion immer noch nicht-polymorph überschreiben. Ist der Zweck von virtual void f() final in der Basisklasse daher, base::f() in irgendeiner Weise fest-nicht-überschreibbar zu machen - entweder als virtuelle oder nicht-virtuelle Funktion? Wenn dem so ist, dann scheint es ein bisschen bedauerlich, dass wir das virtual -Schlüsselwort in diesem Fall nur hinzufügen müssen, um die Verwendung von final zu ermöglichen. Ich würde denken, dass es dann legal sein sollte, auch nicht-virtuelle Funktionen als endgültig zu markieren.

Warum virtual void f() final für eine Funktion verwenden, die aus einer Basisklasse stammt, wenn der Sinn von virtual und der Sinn von final zu widersprechen scheinen?

    
OldPeculier 24.05.2013, 16:01
quelle

3 Antworten

17
  

Ist es sinnvoll, eine Basisklassenfunktion sowohl als virtuell als auch als final zu markieren?

Ja, zumindest vorübergehend.

Ich fand mich in einer relativ großen und unbekannten existierenden C ++ Quellcode-Basis wieder. Ein Großteil des Codes wurde vor C ++ 11 geschrieben. Ich stellte fest, dass ich sicherstellen wollte, dass alle Überschreibungen einer virtuellen Funktion in einer Basisklasse mit override markiert wurden. Der schwierige Teil ist das Auffinden all dieser Überschreibungen.

Ich habe die virtuelle Funktion in der Basisklasse mit final markiert, und der Compiler hat mir schnell gezeigt, wo jeder einzelne Override deklariert wurde. Es war dann sehr einfach, die Overrides zu dekorieren, wie ich wollte, und das final aus dem virtuellen in der Basisklasse zu entfernen.

    
Howard Hinnant 22.10.2014 18:00
quelle
4

Sie können es als virtual markieren, um anzuzeigen, dass es in der Klasse, von der Sie übernommen werden, 'virtuell' ist (obwohl Sie dies nicht tun müssen) und markieren Sie final , um anzugeben, dass keine Klasse abgeleitet wird von Ihrer Klasse kann es weiter überschreiben. Dies kann beispielsweise der Fall sein, wenn Sie eine abstrakte Basisklasse implementieren. Das ist C ++ 11, also ist es nicht nützlich; override ist ein viel besseres Zeichen, da es vom Compiler erzwungen wird.

Eine andere Möglichkeit: Sie möchten, dass diese Methode nicht überschrieben wird, aber Sie möchten dies ohne Neukompilierung ändern können. Denken Sie daran, dass virtual bedeutet, dass es sich in der virtuellen Tabelle befindet. auch wenn der Compiler sie nicht überschreiben lässt.

Ich denke, der Zweck des Beispiels, das Sie gezeigt haben, besteht darin, Prioritäten zwischen virtual und final zu demonstrieren, und nicht mehr. Es ist eine minimale Verwendung von final , keine sinnvolle.

Das Markieren einer nicht virtuellen Methode als final macht keinen Sinn, da Sie sie sowieso nicht überschreiben können. Wenn der Compiler das Ausblenden verhindern soll, ist das ein völlig anderes Problem, das nichts mit der Methode final zu tun hat. In gewissem Sinne sind nicht-virtuelle Methoden bereits endgültig, aber versteckt.

    
Elazar 24.05.2013 16:06
quelle
0

Die Alternative ist eine nicht-virtuelle Funktion. Aber nicht-virtuelle Funktion kann durch eine abgeleitete Klasse verborgen werden. Wenn Sie also verhindern wollen, dass eine Funktion ausgeblendet wird, kann sie als virtuelles Letztes angegeben werden.

    
Paweł Bylica 22.10.2014 11:22
quelle

Tags und Links