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.


Log in to reply