Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung der virtuellen C++-Memberfunktionen und der dynamischen Bindung

Detaillierte Erläuterung der virtuellen C++-Memberfunktionen und der dynamischen Bindung

hzc
hzcnach vorne
2020-07-01 15:33:062035Durchsuche

Empfohlene Studie: „C++-Tutorial

– Der Compiler verwendet statische Bindung für nicht-virtuelle Methoden (Abgleich zur Kompilierungszeit). ), verwenden Sie dynamische Bindung (Laufzeitabgleich) für virtuelle Methoden.

  • Wenn keine virtuellen Methoden verwendet werden, ist der Zeigertyp zur Kompilierungszeit bekannt, sodass der Compiler die Mitgliedsmethode zur entsprechenden aufgerufenen Klasse zur Kompilierungszeit zuordnen kann Statische Bindung;
  • Bei der Verwendung virtueller Methoden kann der Objekttyp normalerweise nur bestimmt werden, wenn das Programm ausgeführt wird, sodass der vom Compiler generierte Code die Mitgliedsfunktion der entsprechenden Klasse zuordnet Das Programm wird ausgeführt, dies wird als dynamische Bindung bezeichnet.

Statische Bindung ist effizienter als dynamische Bindung.

Wie virtuelle Funktionen funktionieren.

Virtuelle Funktion.

Elementfunktionen neu definieren (Funktionssignaturen ändern).

Überladene Memberfunktionen neu definieren.

Effizienz

Damit das Programm zur Laufzeit Entscheidungen treffen kann, muss eine Methode verwendet werden, um den Typ des Objekts zu verfolgen, auf das es zeigt der Basisklassenzeiger oder die Referenz, was zusätzlichen Verarbeitungsaufwand verursacht. Daher eignen sich die folgenden Situationen besser für die statische Bindung:

  • Die Klasse wird nicht als Basisklasse verwendet
  • Die Die abgeleitete Klasse definiert die Basisklasse nicht neu. Jede Methode von

, daher ist die statische Bindung als Standardauswahl für C++ festgelegt.

Wenn Sie eine Basisklassenmethode in einer abgeleiteten Klasse neu definieren möchten, legen Sie sie auf eine virtuelle Methode fest. Andernfalls legen Sie sie auf eine nicht virtuelle Methode fest.

Funktionsweise virtueller Funktionen

Die Art und Weise, wie der Compiler virtuelle Funktionen verarbeitet, besteht darin, jedem Objekt ein verstecktes Mitglied hinzuzufügen. Das ausgeblendete Mitglied speichert einen Zeiger auf das Funktionsadressarray. Dieses Array wird als virtuelle Funktionstabelle (vtbl) bezeichnet und speichert die Adressen virtueller Funktionen, die für Klassenobjekte deklariert wurden.

Das abgeleitete Klassenobjekt enthält einen Zeiger auf eine unabhängige Adresstabelle (d. h. es wird eine neue Tabelle erstellt). (Erhöhter Speicheraufwand)

Beim Aufrufen einer virtuellen Funktion prüft das Programm die im Objekt gespeicherte vtbl-Adresse, wendet sich dann der entsprechenden Funktionsadresstabelle zu und sucht die Adresse in der Tisch. (Beeinflusst die Ausführungsgeschwindigkeit)

Kurz gesagt, die Verwendung virtueller Funktionen verursacht einen gewissen Speicher- und Ausführungsaufwand, auch wenn Nichtfunktionen etwas effizienter sind als virtuelle Funktionen verfügen über eine dynamische Verknüpfungsfunktion.

Der Konstruktor kann keine virtuelle Funktion sein.

Der Destruktor sollte eine virtuelle Funktion sein, es sei denn, die Klasse muss keine Basisklasse sein.

Freundfunktionen können keine virtuellen Funktionen sein, da Freunde keine Klassenmitglieder sind und nur Mitglieder virtuelle Funktionen sein können.

Wenn die abgeleitete Klasse die Funktion nicht neu definiert, wird die Basisklassenversion der Funktion verwendet (erbt sie). Wenn sich eine abgeleitete Klasse in einer Ableitungskette befindet, wird die neueste Version der virtuellen Funktion (Zeiger oder Referenzaufruf) verwendet, es sei denn, die Basisklassenversion ist ausgeblendet.

Durch Neudefinition wird die Basisklassenmethode ausgeblendet:

class Dwelling
{public:    virtual void showperks(int a) const;
    ...
};class Hovel : public Dwelling
{public:    virtual void showperks() const;
    ...
}

Durch Neudefinition der Funktion in der abgeleiteten Klasse (Änderung der Parametersignatur) wird A-Basis ausgeblendet Klassenmethode mit demselben Namen, anstatt eine Basisklassenmethode zu überladen.

Hovel trump;
trump.showperks();    // validtrump.showperks(5);    // invalid

Wenn Sie eine geerbte Methode neu definieren, stellen Sie sicher, dass sie genau mit dem ursprünglichen Prototyp übereinstimmt. Wenn der Rückgabetyp eine Basisklassenreferenz oder ein Zeiger ist, kann er in eine Referenz oder einen Zeiger auf eine abgeleitete Klasse geändert werden (Kovarianz des Rückgabetyps: Das heißt, der Rückgabetyp darf sich ändern, wenn sich der Klassentyp ändert).

Wenn die Basisklassendeklaration überladen ist, sollten alle Basisklassenversionen in der abgeleiteten Klasse neu definiert werden; wenn nur eine Version definiert ist, werden die anderen Versionen nicht ausgeblendet in der Lage sein, sie zu nutzen.

class Dwelling
{public:    virtual void showperks(int a) const;    virtual void showperks(double x) const;    virtual void showperks() const;
    ...
};class Hovel : public Dwelling
{    virtual void showperks(int a) const;    virtual void showperks(double x) const;    virtual void showperks() const;
    ...
};

Wenn keine Änderung erforderlich ist, kann die neue Definition nur die Basisklassenversion aufrufen:

<span class=" cnblogs_code"><span style="color: #0000ff;">void<code> <span class="cnblogs_code"><span style="color: #0000ff;">void</span> Hovel::showperks()<span style="color: #0000ff;">const</span> {Dwelling::showperks();}</span>  Hovel::showperks()const {Dwelling::showperks();}

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der virtuellen C++-Memberfunktionen und der dynamischen Bindung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen