Heim > Backend-Entwicklung > C++ > Warum führt der Aufruf einer virtuellen Funktion in einem Basisklassenkonstruktor dazu, dass die Basisklassenimplementierung verwendet wird?

Warum führt der Aufruf einer virtuellen Funktion in einem Basisklassenkonstruktor dazu, dass die Basisklassenimplementierung verwendet wird?

Barbara Streisand
Freigeben: 2024-12-21 02:03:15
Original
777 Leute haben es durchsucht

Why Does Calling a Virtual Function in a Base Class Constructor Result in the Base Class Implementation Being Used?

Ü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
}
Nach dem Login kopieren

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.

  • Reifung: Während ein Objekt erstellt wird, beginnt es mit den Basisklassenkonstruktoren und „reift“ nach und nach " in den abgeleiteten Klassentyp.

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:

  1. 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;
    Nach dem Login kopieren
  2. 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
    Nach dem Login kopieren
  3. 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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage