Destruktor und this Zeiger



  • @ Konrad Rudolph:
    Wegen der "Effizienz": Wenn du eine Reset() -Methode schreibst, führst du wahrscheinlich einige Zuweisungen bzw. Allokationen und Löschungen in der Klasse durch. Meinst du nicht, das geht schneller als das komplette Zerstören und Neu-Konstruieren des Objekts?



  • Nexus schrieb:

    @ Konrad Rudolph:
    Wegen der "Effizienz": Wenn du eine Reset() -Methode schreibst, führst du wahrscheinlich einige Zuweisungen bzw. Allokationen und Löschungen in der Klasse durch. Meinst du nicht, das geht schneller als das komplette Zerstören und Neu-Konstruieren des Objekts?

    Wo ist der Unterschied? Selbst bei Non-PODs sollte es keinen geben, meine Klasse enthält aber sowieso nur PODs. Also, effizienter bekommt man meinen Code glaube ich wirklich nicht mehr.



  • An dieser Stelle noch eine Frage.

    Folgendes Code-Stück sei gegeben:

    Methode von Klasse1:

    void Klasse1::funktion1() {
      ..
      zeiger_auf_Klasse2_objekt->funktion2(this);
    }
    

    Methode von Klasse2:

    void Klasse2::funktion2(Klasse1* k1) {
      ..
      delete k1;
    }
    

    Das sollte doch ohne Probleme funktionieren oder?
    (vorrausgesetzt Klasse1 wurde mit new erzeugt und es wird nicht mehr darauf zugegriffen nachdem funktion1 aufgerufen wurde)



  • Konrad Rudolph schrieb:

    Wo ist der Unterschied? Selbst bei Non-PODs sollte es keinen geben, meine Klasse enthält aber sowieso nur PODs. Also, effizienter bekommt man meinen Code glaube ich wirklich nicht mehr.

    Ich bin mir da nicht sicher. Wird bei Klassen im Konstruktor nie mehr gemacht als nur Member initialisiert? Oder ist das nur bei polymorphen der Fall?

    xorm schrieb:

    Das sollte doch ohne Probleme funktionieren oder?
    (vorrausgesetzt Klasse1 wurde mit new erzeugt und es wird nicht mehr darauf zugegriffen nachdem funktion1 aufgerufen wurde)

    Nein - das Codestück ist kritisch, weil die Funktion der Klasse selbst noch am Laufen ist, während das Objekt schon zerstört wurde. Zudem wird nachher normalerweise nochmals der Destruktor der (jetzt toten) Klasse aufgerufen.

    Du kannst dir also merken: Objekte können sich nicht selber zerstören. Als "selbst" gilt auch, wenn eine Methode eine andere Funktion aufruft, die das Objekt destruiert. Sowie auch Funktionen, die sich gegenseitig aufrufen, rekursiv sind.



  • Nexus schrieb:

    xorm schrieb:

    Das sollte doch ohne Probleme funktionieren oder?
    (vorrausgesetzt Klasse1 wurde mit new erzeugt und es wird nicht mehr darauf zugegriffen nachdem funktion1 aufgerufen wurde)

    Nein - das Codestück ist kritisch, weil die Funktion der Klasse selbst noch am Laufen ist, während das Objekt schon zerstört wurde. Zudem wird nachher normalerweise nochmals der Destruktor der (jetzt toten) Klasse aufgerufen.

    Daß die Funktion selbst noch am Laufen ist, sollte ja kein Problem sein. Member-Funktionen von Klassen sind schließlich auch nur "normale" Funktionen, denen implizit der this-Zeiger übergeben wird. Nur auf das Objekt selbst darf nach dem delete natürlich in keinster Weise mehr zugegriffen werden.

    Und warum sollte der Destruktor nochmal aufgerufen werden? Daß man nicht ein zweites Mal den selben Zeiger löschen darf ist schon klar, aber das gilt ja unabhängig davon, wer das delete aufruft.
    Mit einem privaten Destruktor könnte man außerdem sicherstellen, daß niemand anders das Objekt zerstören kann, und daß sich keine Objekte der Klasse auf dem Stack erzeugen lassen.



  • Nexus schrieb:

    Du kannst dir also merken: Objekte können sich nicht selber zerstören.

    Doch, können sie. Das war ja gerade der Punkt.



  • dooooomi schrieb:

    Daß die Funktion selbst noch am Laufen ist, sollte ja kein Problem sein.

    Aber kann man sich auch drauf verlassen? Es gibt ja genügend Dinge, die in 99% der Fälle funktionieren...

    dooooomi schrieb:

    Und warum sollte der Destruktor nochmal aufgerufen werden?

    Ich ging dabei von Stack-Deklarationen aus.

    Konrad Rudolph schrieb:

    Doch, können sie. Das war ja gerade der Punkt.

    Hm, dann hab ich das wohl nicht mitgekriegt. Aber mal abgesehen davon, wie sicher das ist - ich finde es vom Design her eher fragwürdig, wenn sich ein Objekt selbst zerstören sollte, gerade mit solchen Dingen wie Destruktor privat und nur new für die Konstruktion zulassen...



  • Nexus schrieb:

    dooooomi schrieb:

    Daß die Funktion selbst noch am Laufen ist, sollte ja kein Problem sein.

    Aber kann man sich auch drauf verlassen? Es gibt ja genügend Dinge, die in 99% der Fälle funktionieren...

    Also, zumindest laut FAQ ist "Selbstmord" von Objekten erlaubt. Ich gehe einfach mal davon aus, daß im C++-Standard nichts gegenteiliges steht.

    Nexus schrieb:

    Aber mal abgesehen davon, wie sicher das ist - ich finde es vom Design her eher fragwürdig, wenn sich ein Objekt selbst zerstören sollte, gerade mit solchen Dingen wie Destruktor privat und nur new für die Konstruktion zulassen...

    In den allermeisten Fällen gibt es sicherlich bessere Lösungen. Aber ich würde delete this (oder eine indirekte Variante davon) nicht zwangsläufig als schlechtes Design ansehen. Manchmal weiß ein Objekt eben selbst am besten, wenn es nicht mehr gebraucht wird.



  • Schreibt anständige Programme, dann braucht ihr sowas komisches garnicht erst.



  • Der "Paradefall" hier wäre intrusive reference counting, wie es z.B. bei COM verwendet wird. (Und in hunderten Frameworks und ...).

    Natürlich könnte man mit dem einen oder anderen Trick das "delete" aus der eigentlichen Klasse rausbekommen. Macht aber IMO keinen Sinn, da ja nix "böse" daran ist.


Anmelden zum Antworten