Was ist die Reihenfolge, in der die Destruktoren und die Konstrukteure in C ++ aufgerufen werden

StackOverflow https://stackoverflow.com/questions/654428

  •  19-08-2019
  •  | 
  •  

Frage

Was ist die Reihenfolge, in der die Destruktoren und die Konstrukteure in C ++ aufgerufen werden? Unter Verwendung der Beispiele einiger Basisklassen und abgeleiteten Klassen

War es hilfreich?

Lösung

Die Reihenfolge lautet:

  1. Basiskonstruktor
  2. Abgeleitet Konstruktor
  3. Abgeleitet destructor
  4. Basis destructor

Beispiel:

class B
{
public:
  B()
  {  
    cout<<"Construct B"<<endl;
  }

  virtual ~B()
  {
    cout<<"Destruct B"<<endl;
  }
};

class D : public B
{
public:
  D()
  {  
    cout<<"Construct D"<<endl;
  }

  virtual ~D()
  {
    cout<<"Destruct D"<<endl;
  }
};



int main(int argc, char **argv)
{
  D d; 
  return 0;
}

Ausgabe Beispiel:

  

Construct B

     

Construct D

     

Destruct D

     

Destruct B

Mehrere Ebenen der Vererbung funktioniert wie ein Stapel:

Wenn Sie ein Element auf dem Stapel als Konstruktion betrachten schieben, und es ab, als Zerstörung nehmen, dann können Sie wie ein Stapel auf mehreren Ebenen der Vererbung aussehen.

Dies funktioniert für eine beliebige Anzahl von Ebenen.

Beispiel D2 leitet sich von D von B ableitet.

Push B auf den Stapel schieben D auf den Stapel schieben D2 auf den Stapel. So ist die Konstruktion ist, um B, D, D2. Dann, um herauszufinden, Zerstörung beginnen knallen. D2, D, B

Kompliziertere Beispiele:

Für kompliziertere Beispiele finden Sie auf den Link von @JaredPar zur Verfügung gestellt

Andere Tipps

Eine detaillierte Beschreibung dieser Ereignisse, einschließlich virtueller und Mehrfachvererbung ist in der C ++ FAQ Lite zur Verfügung. Abschnitt 25.14 und 25.15

https://isocpp.org/wiki/faq/ Mehrfachvererbung # mi-vi-ctor Ordnung

Auch beachten Sie, dass während Array-Elemente zuerst konstruiert werden -> letzten, sie in der umgekehrten Reihenfolge zerstört werden. Letzte -> erster

Ich muss auf die bisherigen Antworten hinzufügen, weil jeder es zu ignorieren scheint

Wenn Sie eine haben abgeleitet Klasseninstanz zu sein erstellt , es ist wahr, dass der Code innen der Konstruktor der Basis wird vor innen der Konstruktor der abgeleitet der Code namens werden halten, aber bedenken, dass die abgeleitet immer noch nicht technisch "erstellt" vor Basis .

Und wenn Sie die haben abgeleitet Klassendestruktor genannt wird, ist es wahr, dass der Code innen die abgeleitete destructor heißt vor der Code innen die Basis destructor, aber auch bedenken, dass die Basis ist zerstört vor abgeleitet .

Wenn ich sage erstellt / zerstört Ich beziehe mich tatsächlich auf zugewiesen / deallokierten .

Wenn Sie auf dem Speicherlayout dieser Instanzen betrachten, sehen Sie, dass die abgeleitete Instanz komponiert die Basis-Instanz. Zum Beispiel:

Speicher abgeleiteter: 0x00001110 auf 0x00001120

Speicher von Base: 0x00001114 auf 0x00001118

Daher muss die abgeleitete Klasse zugeordnet wird Vor die Basis in der Konstruktion. Und die abgeleitete Klasse muß ausgeplant wird nach der Basis in der Zerstörung.

Wenn Sie den folgenden Code:

class Base 
{
public:
    Base()
    {
        std::cout << "\n  Base created";
    }
    virtual ~Base()
    {
        std::cout << "\n  Base destroyed";
    }
}

class Derived : public Base 
{
public:
    Derived()
    // Derived is allocated here 
    // then Base constructor is called to allocate base and prepare it
    {
        std::cout << "\n  Derived created";
    }
    ~Derived()
    {
        std::cout << "\n  Derived destroyed";
    }   
    // Base destructor is called here
    // then Derived is deallocated
}

Wenn Sie also Derived d; erstellt und hatte es den Gültigkeitsbereich gehen, dann werden Sie die Ausgabe in @ Brians Antwort. Aber das Objektverhalten im Speicher ist nicht wirklich die in derselben Reihenfolge, ist es wie folgt aus:

Konstruktion:

  1. Abgeleitet zugewiesen

  2. Basis zugewiesen

  3. Basis-Konstruktor aufgerufen

  4. Abgeleitet Konstruktor aufgerufen

Zerstörung:

  1. Abgeleitet destructor genannt

  2. Basis destructor genannt

  3. Basis ausgeplant

  4. Abgeleitet ausgeplant

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top