Überschreiben virtueller Funktionen in Konstruktoren
Betrachten Sie den folgenden Codeausschnitt:
#include <iostream> struct base { virtual const int value() const { return 0; } base() { // Default constructor std::cout << value() << std::endl; } }; struct derived : public base { virtual const int value() const { return 1; } }; int main() { derived d; // Declares an instance of the derived class }
Wenn wir diesen Code ausführen, es gibt 0 statt der erwarteten 1 aus. Warum?
Virtueller Funktionsaufruf während der Konstruktion
Wenn ein Basisklassenkonstruktor eine virtuelle Funktion im Konstruktor aufruft, wird die virtuelle Funktion nicht auf der Basisklasseninstanz aufgerufen die abgeleitete Klasseninstanz. Dies ist ein Ergebnis des „Reifungsprozesses“ des Objekts während der Konstruktion.
In unserem Beispiel ruft der Basiskonstruktor value() auf, wenn das Objekt teilweise konstruiert ist. Zu diesem Zeitpunkt ist das Objekt noch nicht zu einem abgeleiteten Objekt „gereift“. Somit wird die ursprüngliche Basisimplementierung von value() aufgerufen.
So beheben Sie das Problem
Damit der Code 1 ausgibt, können Sie den Aufruf der virtuellen Funktion vermeiden im Konstruktor. Dies kann erreicht werden durch:
Verwendung eines Zeigers: Rufen Sie die virtuelle Funktion von einem Zeiger oder einer Referenz auf die Basisklasse auf, anstatt direkt von ihrer Mitgliedsfunktion:
base* b = new derived(); b->value(); // Calls the derived class implementation delete b;
Verwenden einer Mitgliedsinitialisierungsliste:Verwenden Sie ein Mitglied Initialisierungsliste, um den Wert der virtuellen Funktion im Konstruktor explizit anzugeben:
derived d : base() { } // Initializes `base()` and the virtual function // call to occur within the constructor
Das obige ist der detaillierte Inhalt vonWarum führt der Aufruf einer virtuellen Funktion in einem Basisklassenkonstruktor dazu, dass die Basisklassenimplementierung verwendet wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!