Funktionsüberschreibung und Überlastung in C ++ und Delphi
Spacesoft 【Dark Night Sand】
In objektorientierter Programmierung muss die Unterklasse, wenn die Unterklasse die Funktionen aus der Basisklasse fortsetzt, möglicherweise mit einigen der Funktionen anders um die Basisklasse umgehen, wie z. B.:
Klassenchuman
{
öffentlich:
void saymyname () // den Namen des Objekts ausdrucken
{
cout << Hallo, ich bin ein Mensch << endl;
}
};
Dann ist es offensichtlich, wenn die Unterklasse eine Funktion Saymyname mit demselben Namen, demselben Parameter und dem Rückgabewert (ein Satz, dieselbe Funktion) hat, welche Funktion wird es aufrufen? Zum Beispiel gibt es jetzt ein CLASS -CMARK
Klasse Cmark: öffentlicher Chuman
{
öffentlich:
void saymyname ()
{
cout << hi, ich bin mark << endl;
}
};
Dann müssen wir uns nach dem folgenden Programmsegment fragen:
Chuman *PH = New Cmark;
if (pH)
ph-> saymyname ();
anders
cout << Fehler! << endl;
pH löschen;
PH = NULL;
Ist das Hallo, ich bin Mark, den wir ausdrucken wollen?
NEIN. Es gibt Hallo aus, ich bin ein Mensch. Es ist schrecklich, und wenn wir auf eine Person zeigen und ihn bitten, seinen Namen zu sagen, sagt er uns, dass er "eine Person" ist, anstatt seinen Namen zu sagen. Der Grund für dieses Problem ist, dass Sie auf die öffentlich abgeleitete Klasse mit dem Basisklassenzeiger auf die Mitgliederfunktionen der abgeleiteten Klasse zugreifen können, die von der Basisklasse fortgesetzt werden. Wenn es jedoch Funktionen mit demselben Namen in der abgeleiteten Klasse gibt, greift das Ergebnis immer noch auf die Funktion desselben Namens der Basisklasse und nicht auf die Funktion der abgeleiteten Klasse selbst. In der Tat wollen wir feststellen, welche dieser gleichnamigen Funktionen von der tatsächlichen Art eines Objekts aufgerufen werden sollten, dh eine solche Auflösung ist dynamisch. Oder wir können sagen, dass wenn ein Objekt ein Subtyp ist, seine gleichnamige Implementierung in der Unterklasse die Implementierung der Basisklasse überschreibt.
Beginnen wir mit dem Umgang mit C ++ mit diesem Problem.
Dies ist ein typisches Beispiel für Polymorphismus in C ++. C ++ verwendet virtuelle Funktionen, um einen solchen Polymorphismus zu implementieren. Um spezifisch zu sein, werden virtuelle Schlüsselwörter verwendet, um die Funktion als virtuelle Funktion zu beschreiben.
Klassenchuman
{
öffentlich:
Virtuelle Void Saymyname () // Drucken Sie den Namen des Objekts aus
{
cout << Hallo, ich bin ein Mensch << endl;
}
};
Auf diese Weise sind andere Codes immer noch gleich, aber unser Cmark weiß bereits, wie man seinen Namen sagt. Es spielt keine Rolle, ob die Funktion von saymyname () von cmark ein virtuelles Schlüsselwort hinzugefügt hat, da nach den Bestimmungen der C ++ - Syntax die gleichnamige Chuman -Funktion überschreibt, wird sie selbst virtuell. Warum hat ein virtuelles Schlüsselwort einen so magischen Effekt? C ++ - FAQ Lite erklärt dies wie folgt: In C ++ werden virtuelle Elementfunktionen dynamisch bestimmt (zur Laufzeit). Die Elementfunktionen (zur Laufzeit) werden dynamisch ausgewählt und die Auswahl basiert auf dem Typ des Objekts. die Art des Zeigers/Verweis auf dieses Objekt ". Unser pH -Wert stellt also fest, dass er tatsächlich auf ein Objekt vom Typ Cmark zeigt, nicht auf den Chuman, der von seinem eigenen Typ deklariert wurde, und so ruft Cmarks Saymyname geschickt auf.
Delphi verwendet Override -Schlüsselwörter, um Funktionsüberschreibungen zu veranschaulichen. Die überschriebene Funktion muss virtuell oder dynamisch sein, dh die Funktion sollte eine dieser beiden Indikatoren enthalten, wenn sie deklariert werden, wie z. B.:
Verfahren zeichnen;
Wenn Sie überschreiben müssen, müssen Sie es nur mit dem Override -Indikator in der Unterklasse neu anklären.
Verfahren zeichnen;
Syntaktisch sind Deklarationen als virtuell und dynamisch gleichwertig. Der Unterschied besteht darin, dass erstere die Geschwindigkeit bei der Implementierung optimiert, während letztere die Codegröße optimiert.
Was ist, wenn sowohl die Basisklasse als auch die Unterklasse den gleichen Funktionsnamen und denselben Parameter enthalten und die Unterklasse nicht zur Unterklasse hinzugefügt wird? Dies ist auch syntaktisch korrekt. Dies bedeutet, dass die Funktion der Funktion der Funktion der Subklasse die Implementierung der Basisklasse verbirgt, obwohl beide in der abgeleiteten Klasse existieren. Dann kehren wir zu der Situation zurück, die im ersten Beispiel zu Beginn dieses Artikels gezeigt wurde: Wenn wir auf eine Person hinweisen und ihn bitten, seinen eigenen Namen zu sagen, sagt er uns, dass er "eine Person" ist, anstatt seine eigenen zu sagen Name.
Es ist erwähnenswert, dass im Gegensatz zur Überladungsfunktion und der Überladungsfunktion, die wir in C ++ häufig aufrufen, in Delphi nur das Überladung von Überladungen in der Regel überlastet. Wenn die Funktion der Funktion überlastet ist, ist die Funktionsparameter der Basisklasse natürlich übereinstimmt, die Implementierung der Basisklasse versteckt, genau wie der oben erwähnte. Override bedeutet, dass die überschriebene Funktion unsichtbar und in der Tat überschreibt, und die ursprüngliche Implementierung wird verschwinden. Aus diesem Grund haben viele Artikel und sogar einige Bücher eine Überlastung fälschlicherweise überlastet, was meiner Meinung nach nicht angemessen ist.