Soll ich alle Funktionen in einer Basisklasse virtuell deklarieren?

8

Wenn ich eine Basisklasse deklariere, sollte ich alle darin enthaltenen Funktionen als virtuell deklarieren, oder sollte ich eine Menge virtueller Funktionen und eine Menge nicht virtueller Funktionen haben, von denen ich sicher bin, dass sie nicht vererbt werden? / p>     

excray 07.05.2009, 12:17
quelle

8 Antworten

7

Eine Funktion muss nur virtuell sein, wenn eine abgeleitete Klasse diese Funktion auf andere Weise implementiert.

Zum Beispiel:

%Vor%

Als Ergebnis würde ich die Seite, die nichts virtuell hat, fälschen, wenn Sie nicht im Voraus wissen, dass Sie beabsichtigen, es zu überschreiben, oder bis Sie feststellen, dass Sie das Verhalten benötigen. Die einzige Ausnahme ist der Destruktor, für den fast immer der Fall ist, dass er in einer Basisklasse virtuell sein soll.

    
Richard Corden 07.05.2009, 12:26
quelle
4

Sie sollten nur Funktionen machen, die Sie beabsichtigen, virtuell zu überschreiben. Eine Methode virtuell zu machen ist nicht frei in Bezug auf Wartung und Leistung (Wartung ist das viel größere Problem IMHO).

Sobald eine Methode virtuell ist, wird es schwieriger, über irgendeinen Code nachzudenken, der diese Methode verwendet. Anstatt zu überlegen, was ein Methodenaufruf tun würde, müssen Sie überlegen, welche N-Methodenaufrufe in diesem Szenario ausgeführt würden. N gibt die Anzahl der Unterklassen an, die diese Methode überschreiben.

Die einzige Ausnahme von dieser Regel sind Destruktoren. Sie sollten in jeder Klasse virtuell sein, von der abgeleitet werden soll. Nur so kann sichergestellt werden, dass der richtige Destruktor während der Freigabe aufgerufen wird.

    
JaredPar 07.05.2009 13:11
quelle
4

Das nicht-virtuelle Schnittstellen-Idiom (C ++ Coding Standards, Element 39) besagt, dass eine Basisklasse über nicht virtuelle Schnittstellenmethoden verfügen sollte, die es der Basisklasse ermöglichen, Invarianten zu garantieren, und nicht-öffentliche virtuelle Methoden zur Anpassung des Basisklassenverhaltens durch abgeleitete Klassen. Die nicht virtuellen Schnittstellenmethoden rufen die virtuellen Methoden auf, um das überschreibbare Verhalten bereitzustellen.

    
andreas buykx 07.05.2009 14:02
quelle
2

Ich tendiere dazu, nur die Dinge virtuell übersteuerbar zu machen. Wenn meine anfänglichen Annahmen über das, was ich außer Kraft setzen möchte, falsch sind, gehe ich zurück und ändere die Basisklasse.

Oh, und natürlich machen Sie Ihren Destruktor immer virtuell, wenn Sie an etwas arbeiten, von dem er geerbt wird.

    
Dominic Rodger 07.05.2009 12:19
quelle
1

Wenn Sie eine Basisklasse erstellen (Sie sind sicher, dass jemand die Klasse ableitet), können Sie folgende Dinge tun:

  • Machen Sie den Destruktor virtuell (ein Muss für die Basisklasse)
  • Definieren Sie Methoden, die sein sollten abgeleitet und machen sie virtuell.
  • Definieren Sie Methoden, die nicht sein müssen (oder sollte nicht abgeleitet werden als nicht virtuell.
  • Wenn die Funktionen nur für abgeleitet sind Klasse und nicht für Basisklasse dann markieren sie als geschützt.
aJ. 07.05.2009 12:24
quelle
1

Der Compiler würde nicht wissen, welcher Code tatsächlich ausgeführt wird, wenn der Zeiger des Basistyps eine virtuelle Funktion aufruft. Daher muss der tatsächliche Codeabschnitt, der ausgeführt werden soll, zur Laufzeit ausgewertet werden, abhängig davon, auf welches Objekt der Basisklassenzeiger zeigt. Vermeiden Sie daher die Verwendung virtueller Funktionen, wenn die Funktion in einer geerbten Klasse nicht überschrieben werden soll.

TLDR-Version: "Sie sollten eine Reihe von virtuellen Funktionen und eine Reihe von nicht-virtuellen Funktionen haben, von denen Sie sicher sind, dass sie nicht vererbt werden." Weil virtuelle Funktionen zur Laufzeit eine Leistungsminderung verursachen.

    
Numenor 07.05.2009 12:49
quelle
0

Die Schnittstellenfunktionen sollten im Allgemeinen virtuell sein. Funktionen, die feste Funktionalität bieten, sollten nicht.

    
PaulJWilliams 07.05.2009 12:18
quelle
0

Warum erklären Sie etwas virtuell, bis Sie es wirklich überschreiben? Ich glaube, es geht nicht darum, sicher zu sein oder nicht. Befolgen Sie die Fakten: Wird es irgendwo überschrieben? Nein? Dann muss es nicht virtuell sein.

    
Ivan Krechetov 07.05.2009 12:24
quelle

Tags und Links