- Ja, sie sind gleich. Die abgeleitete Klasse, die etwas nicht als virtuell deklariert, hindert es nicht daran, virtuell zu sein. Tatsächlich gibt es keine Möglichkeit, zu verhindern, dass eine Methode (einschließlich Destruktor) in einer abgeleiteten Klasse virtuell ist, wenn sie in einer Basisklasse virtuell war. In> = C ++ 11 können Sie
final
verhindern, dass es in abgeleiteten Klassen überschrieben wird, aber das verhindert nicht, dass es virtuell ist.
- Ja, ein Destruktor in einer abgeleiteten Klasse kann weggelassen werden, wenn er nichts zu tun hat. Und es spielt keine Rolle, ob es virtuell ist oder nicht.
- Ich würde es wenn möglich weglassen. Und ich verwende das
virtual
Schlüsselwort aus Gründen der Klarheit immer wieder für virtuelle Funktionen in abgeleiteten Klassen. Die Benutzer sollten nicht die gesamte Vererbungshierarchie nach oben gehen müssen, um herauszufinden, dass eine Funktion virtuell ist. Wenn Ihre Klasse kopierbar oder verschiebbar ist, ohne dass Sie Ihre eigenen Kopier- oder Verschiebungskonstruktoren deklarieren müssen, werden Sie durch Deklarieren eines Destruktors jeglicher Art (auch wenn Sie ihn als definieren default
) gezwungen, die Kopier- und Verschiebungskonstruktoren und Zuweisungsoperatoren zu deklarieren, wenn Sie möchten Sie als Compiler werden sie nicht mehr für Sie eingeben.
Als kleiner Punkt für Punkt 3. In Kommentaren wurde darauf hingewiesen, dass der Compiler, wenn ein Destruktor nicht deklariert ist, einen Standard generiert (der immer noch virtuell ist). Und diese Standardeinstellung ist eine Inline-Funktion.
Inline-Funktionen setzen möglicherweise mehr Ihres Programms Änderungen in anderen Teilen Ihres Programms aus und machen die Binärkompatibilität für gemeinsam genutzte Bibliotheken schwierig. Außerdem kann die erhöhte Kopplung angesichts bestimmter Arten von Änderungen zu einer starken Neukompilierung führen. Wenn Sie beispielsweise entscheiden, dass Sie wirklich eine Implementierung für Ihren virtuellen Destruktor wünschen, muss jeder Code, der ihn aufgerufen hat, neu kompiliert werden. Wenn Sie es im Klassenkörper deklariert und dann in einer .cpp
Datei als leer definiert hätten, könnten Sie es problemlos ändern, ohne es neu zu kompilieren.
Meine persönliche Entscheidung wäre immer noch, es wegzulassen, wenn es möglich ist. Meiner Meinung nach ist der Code unübersichtlich, und der Compiler kann manchmal mit einer Standardimplementierung etwas effizienter arbeiten als mit einer leeren. Aber es gibt Einschränkungen, unter denen Sie möglicherweise stehen, die dies zu einer schlechten Wahl machen.