Wenn ich eine Basisklasse (oder Schnittstellenklasse) deklariere und einen Standardwert für einen oder mehrere ihrer Parameter spezifiziere, müssen die abgeleiteten Klassen dieselben Standardwerte angeben, und wenn nicht, welche Standardwerte werden in den abgeleiteten Klassen angezeigt?
Nachtrag: Ich bin auch daran interessiert, wie dies über verschiedene Compiler hinweg gehandhabt werden kann und welche Eingaben zur "empfohlenen" Praxis in diesem Szenario vorliegen.
Antworten:
Virtuals haben möglicherweise Standardeinstellungen. Die Standardeinstellungen in der Basisklasse werden nicht von abgeleiteten Klassen geerbt.
Welche Standardeinstellung verwendet wird, dh die Basisklasse 'oder eine abgeleitete Klasse', wird durch den statischen Typ bestimmt, der zum Aufrufen der Funktion verwendet wird. Wenn Sie ein Basisklassenobjekt, einen Zeiger oder eine Referenz aufrufen, wird der in der Basisklasse angegebene Standard verwendet. Wenn Sie dagegen ein abgeleitetes Klassenobjekt, einen Zeiger oder eine Referenz aufrufen, werden die in der abgeleiteten Klasse angegebenen Standardwerte verwendet. Unter dem Standardzitat befindet sich ein Beispiel, das dies demonstriert.
Einige Compiler machen möglicherweise etwas anderes, aber dies ist, was die C ++ 03- und C ++ 11-Standards sagen:
Hier ist ein Beispielprogramm, um zu demonstrieren, welche Standardeinstellungen übernommen wurden. Ich verwende
struct
hier eher s alsclass
nur der Kürze halber -class
und binstruct
in fast jeder Hinsicht genau gleich, mit Ausnahme der Standardsichtbarkeit.Die Ausgabe dieses Programms (unter MSVC10 und GCC 4.4) lautet:
quelle
Dies war das Thema eines der frühen Guru of the Week- Beiträge von Herb Sutter .
Das erste, was er zu diesem Thema sagt, ist, das nicht zu tun.
Ja, Sie können verschiedene Standardparameter angeben. Sie funktionieren nicht wie die virtuellen Funktionen. Für den dynamischen Typ des Objekts wird eine virtuelle Funktion aufgerufen, während die Standardparameterwerte auf dem statischen Typ basieren.
Gegeben
Sie sollten A :: foo1 B :: foo2 B :: foo1 erhalten
quelle
Dies ist eine schlechte Idee, da die Standardargumente, die Sie erhalten, vom statischen Typ des Objekts
virtual
abhängen , während die Funktion, an die gesendet wird, vom dynamischen Typ abhängt .Das heißt, wenn Sie eine Funktion mit Standardargumenten aufrufen, werden die Standardargumente beim Kompilieren ersetzt, unabhängig davon, ob es sich um eine Funktion handelt
virtual
oder nicht.@cppcoder hat in seiner [geschlossenen] Frage das folgende Beispiel angeboten :
Welches erzeugt die folgende Ausgabe:
Anhand der obigen Erklärung ist leicht zu erkennen, warum. Zur Kompilierungszeit ersetzt der Compiler die Standardargumente aus den Elementfunktionen der statischen Typen der Zeiger, sodass die
main
Funktion der folgenden entspricht:quelle
Wie Sie den anderen Antworten entnehmen können, ist dies ein kompliziertes Thema. Anstatt dies zu versuchen oder zu verstehen, was es tut (wenn Sie jetzt fragen müssen, muss der Betreuer in einem Jahr danach fragen oder nachschlagen).
Erstellen Sie stattdessen eine öffentliche nicht virtuelle Funktion in der Basisklasse mit Standardparametern. Anschließend wird eine private oder geschützte virtuelle Funktion aufgerufen, die keine Standardparameter hat und bei Bedarf in untergeordneten Klassen überschrieben wird. Dann müssen Sie sich keine Gedanken darüber machen, wie es funktionieren würde, und der Code ist sehr offensichtlich.
quelle
Dies ist eine, die Sie wahrscheinlich durch Testen ziemlich gut herausfinden können (dh es ist ein ausreichend allgemeiner Teil der Sprache, dass die meisten Compiler es mit ziemlicher Sicherheit richtig machen, und wenn Sie keine Unterschiede zwischen Compilern sehen, kann ihre Ausgabe als ziemlich maßgeblich angesehen werden).
quelle
Wie andere Antworten ausführlich dargelegt haben, ist es eine schlechte Idee. Da jedoch niemand eine einfache und effektive Lösung erwähnt, ist dies hier: Konvertieren Sie Ihre Parameter in struct und dann können Sie Standardwerte für struct-Mitglieder festlegen!
Also statt
mach das,
quelle