2017-12-10 11 views
1

Dies ist ein Code, den ich versucht habe zu verstehen, wie es funktioniert.Warum wird Destructor aufgerufen

#include <iostream> 

using namespace std; 

class A 
{ 
public: 
    int variable; 

    A() 
    { 
     cout << "Default Constructor\n"; 
    } 

    A(int variable_) 
    { 
     cout << "Overloaded Constructor\n"; 
     variable = variable_; 
    } 

    A(A& Object) 
    { 
     cout << "Copy Constructor\n"; 
     variable = Object.variable; 
    } 

    ~A() 
    { 
     cout << "Destructor\n"; 
    } 
}; 

void main() 
{ 
    { 
     A* PA1 = new A(1); 

     cout << "\n"; 

     A* PA2 = &(A(*(PA1))); 

     cout << "Second\n\n"; 

     A* PA3 = &(A(1)); 

     cout << "\n"; 

     A* PA4 = new A(*(PA3)); 
    } 



    cout << "\n"; 
    system("pause"); 
} 

Warum destructor nach der Initialisierung von PA2 genannt wird? Was bedeutet das - &(A(*(PA1))) and &(A(1))?

Dies ist Ausgabe dieses Codes:

enter image description here

+2

Und Sie haben keine Warnung wie "Adresse von tempororary" erhalten? –

+0

* Warum wird Destruktor aufgerufen * - Ihre Ausgabe fehlt. Sie sollten den Wert von "this" ausgeben, um zu verstehen oder eine Idee zu bekommen **, welcher ** Destruktor oder Konstruktor aufgerufen wird. – PaulMcKenzie

+0

PaulMcKenzie ich tat es aber A * PA2 = & (A (* (PA1))); indem PA2 so deklariert wird, wird Destruktor für dieselbe Adresse wie die von PA2 aufgerufen! Ich weiß nicht, was hier wirklich vor sich geht! –

Antwort

0

&(A(*(PA1))) ruft A(*(PA1)) auf und gibt einen Zeiger auf die Variable zurück. Da dies ein Konstruktor ist, wird eine Variable vom Typ A zurückgegeben, und da Sie eine Variable vom Typ A übergeben, ruft sie den Kopierkonstruktor auf. Dies ist kein guter Code, da die Rückgabe im temporären Speicher ist. Das Verhalten dafür ist nicht definiert, Sie sollten dies also niemals beim Schreiben von Code verwenden.

macht dasselbe wie oben, ruft aber den Konstruktor auf, der ein int akzeptiert, weil das das ist, was Sie ihm übergeben.

Der Grund, warum der Destruktor aufgerufen wird, ist, weil C++ automatisch Variablen zerstört, die nicht verwendet werden und deren Geltungsbereich abläuft. Wenn Sie also den Konstruktor aufrufen, ohne das Schlüsselwort new zu verwenden, wird das Objekt erstellt, aber Sie speichern es nicht an einer beliebigen Stelle. Sie speichern ihre Adresse, die wie oben angegeben ein nicht definiertes Verhalten ist. Daher wird der vom Konstruktor zurückgegebene Wert (der aus diesem Grund als temporär bezeichnet wird) sofort zerstört.

0

Weil sie temporäre Objekte sind und getötet werden, wenn sie außerhalb des Bereichs sind.

& (A (* (PA1))) bedeutet eine Adresse eines Objekts von A, das mit dem Kopierkonstruktor mit der Eingabevariablen erstellt wird, auf die PA1 zeigt.

& (A (1)) bedeutet, eine Adresse eines Objektes von A, die mit Copykonstruktor mit Eingangsgröße 1.

In beiden Fällen sind diese Gegenstände vorübergehend sind konstruiert ist.

0

Ihre Anweisung A* PA3 = &(A(1)) erstellt ein temporäres Objekt, das direkt nach der Anweisung zerstört wird. Daher wird der Destruktor an diesem Punkt aufgerufen, d. H. Direkt nach der Anweisung.

Es scheint, als ob Sie mit der Tatsache gekämpft haben, dass PA3 immer noch auf die Adresse des (zerstörten) temporären Objekts zeigt.

Beachten Sie, dass das Zerstören eines Objekts in C++ keinen Zeiger auf dieses Objekt ändert/zurücksetzt. Es ist nur definiert, dass der Zugriff auf ein gelöschtes Objekt durch einen solchen Zeiger ein undefiniertes Verhalten auslöst. So ist es nicht verwunderlich, dass PA3 auf die gleiche Adresse wie die this des temporären Objekts zeigt. Die Dereferenzierung dieses Zeigers führt jedoch zu undefiniertem Verhalten.

Verwandte Themen