Konstruktor und Dekonstruktor



  • Hallo ,

    meine Frage ist , wann / wie diese Aktiviert werden.
    Bzw. Wie die Klasse Stack genau arbeitet.

    class Stack 
    {
    private:
    	int data[MAX];
    	int size;
    
    public:
    	Stack();  // Constructor
    	~Stack(); // Destructor
    	int top();
    	void push(int d); 
    	void pop();
    	void show();
    };
    

    Danke schonmal im voraus 👍


  • Mod

    Der Konstruktor wird aufgerufen, wenn ein Objekt entsteht, der Destruktor wenn es zerstört wird. Dies findet normalerweise an den Grenzen des Gültigkeitsbereichs (also den eckigen Klammern) statt, die das Objekt umschließen. Oder vor dem Konstruktor bzw. nach dem Destruktor eines übergeordneten Objekts. Oder bei new und delete. Oder in temporären Ausdrücken. Es gibt so viele Methoden, Objekte zu erstellen und zu zerstören.



  • Also wird der Konstruktor nach der ) aufgerufen und steht dann im Speicher?



  • {
    Stack my_Stack;     //Konstruktor wird aufgerufen
    
    }//Destruktor wird aufgerufen
    
    {
    Stack *my_Stack = new Stack();    //Konstruktor wird aufgerufen
    
    } //Destruktor wird nicht aufgerufen
    
    delete my_Stack;    //Destruktor wird aufgerufen
    

    Der Konstruktor wird aufgerufen, wenn du ein Objekt entstehen lässt, und der Destruktor, wenn der Gütigkeitsbereich verlassen wird oder es per Hand gelöscht wird.

    gruß
    syntax



  • Syntax_error schrieb:

    {
    Stack my_Stack;     //Konstruktor wird aufgerufen
    
    }//Destruktor wird aufgerufen
    
    {
    Stack *my_Stack = new Stack();    //Konstruktor wird aufgerufen
    
    } //Destruktor wird nicht aufgerufen
    
    delete my_Stack;    //Destruktor wird aufgerufen
    

    Nö, hier wird wohl kein Destruktor aufgerufen ... zumindest nicht für das in obigem Code erstellte Objekt.



  • hmm wie denn jetzt??



  • Na, überleg mal: Da, wo delete aufgerufen wird, ist die in dem darüberliegenden Scope definierte Variable gar nicht mehr bekannt.



  • So meint er es:

    Stack *my_Stack;
    {
    my_Stack = new Stack();    //Konstruktor wird aufgerufen
    
    } //Destruktor wird nicht aufgerufen
    
    delete my_Stack;    //Destruktor wird aufgerufen
    

  • Mod

    berndderbernd schrieb:

    hmm wie denn jetzt??

    Die Idee von Syntax_error war schon richtig, er hat bloß nicht da drauf geachtet, dass der Destruktor von my_Stack (also dem Pointer) vorher aufgerufen wird, wodurch der Code nicht funktioniert:

    {
     Stack* ptr1;    // Konstruktor von ptr1 wird aufgerufen (der genau nichts macht)
     {
      Stack *ptr2 = new Stack();    //Konstruktor von Stack und ptr2 wird aufgerufen
      ptr1 = ptr2;
     } //Destruktor von Stack wird nicht aufgerufen, aber ptr2 wird zerstört (was auch genau nichts macht)
     delete ptr2;    //Destruktor von Stack wird aufgerufen 
    } // Destruktor von ptr1 wird aufgerufen (wieder: Macht überhaupt gar nichts)
    


  • Aber jetzt steh ich auf dem Schlauch! 😕
    Was ist an meinem Code verkehrt?

    gruß
    syntax



  • Bei der Definition eines Objektes wird dessen Konstruktor aufgerufen.

    extern int a;//Deklaration, hier geschieht nix als Namensfestlegung
    
    int b;//Definition; bei globalen Variablen muss aber Deklaration/Definition aufgeteilt werden um die ODR nicht zu verletzen (falls man mehrere Übersetzungseinheiten hat wird sonst der Linker verwirrt)
    

    Bei Stackobjekten werden beim Verlassen des Scopes in Reihenfolge der Instantiierung die Destruktoren aufgerufen.

    {
    std::string a;
    std::vector<int> b(100, 5);
    
    }//Zuerst b->~vector(), dann a->~string()
    

    Bei abgeleiteten Klassen wird zuerst der Destruktor der Kindklasse, dann der der Basisklasse aufgerufen, also absteigend.

    #include <iostream>
    
    struct A
    {
            virtual ~A()
            {
                    std::cout << "AA!\n";
            }
    };
    
    struct B : public A
    {
            ~B()
            {
                    std::cout << "BB!\n";
            }
    };
    
    struct C : public B
    {
            ~C()
            {
                    std::cout << "CC!\n";
            }
    };
    
    int main()
    {
            C b;
    }
    

    Konsole schrieb:

    CC!
    BB!
    AA!

    Bei Heapobjekten (also Objekten die im Freispeicher liegen) werden Kon/De-struktor zusammen mit new / delete aufgerufen. Dadurch kann man also selbst über die Lebensdauer eines Objektes entscheiden, was aber auch - wie Syntax_errors Code zeigt - zu Speicherlecks führen kann, und Bugs die man lange suchen darf (und mit lange meine ich lange).

    @Syntax_error: Alter, du vergisst local-scopes. Bei deinem Code entstehen definitiv Speicherlecks.



  • Syntax_error schrieb:

    Aber jetzt steh ich auf dem Schlauch! 😕
    Was ist an meinem Code verkehrt?

    gruß
    syntax

    na das Stack Objekt ist schon noch am Heap, das passt schon.
    Nur der Zeiger ist futsch, da er innerhalb des { } definiert wurde. Schließlich kannste delete nicht auf diesen Zeiger ausführen.


Anmelden zum Antworten