Objekt einer Klasse: Selbstzerstörung
-
class SuicideClass { public: void CommitSuicide() { delete this; } }; int _tmain(int argc, _TCHAR* argv[]) { SuicideClass *sc = new SuicideClass; sc->CommitSuicide(); return 0; }
Wobei zu beachten ist, das nach CommitSuicide kein delete mehr kommen darf, sonnst RT-error.
-
Sprich: Ich muss das Objekt dynamisch erzeugen (und nicht auf dem Stack, wie in meinem Beispiel). Danke!
-
Exakt, da der Compiler das Objekt sonst killen will, wenn es nicht mehr gültig ist -> 2facher Destruktoraufruf.
Gern geschehen
-
Warum geht folgendes?
class foo { public: void KillMe() { delete this; } void TestMe() { cout << "Ich lebe noch" << endl; } }; #pragma argsused int main(int argc, char* argv[]) { foo* p = new foo; p->KillMe(); p->TestMe(); }
-
Gute Frage, das delete tut genau nix...
-
Laut Standard ist das Verhalten deines Beispiels undefiniert, sprich es kann alles passieren selbst funktionieren. Allerdings muss das auf anderen Compilern nicht der Fall sein.
@otze bei GUIs halte ich die Anwendung von delete this für schlecht und ich bin mir ziehmlich sicher, dass da der Fehlerteufel wüten wird, spätestens wenn Ausnahmen fliegen.
Ich würde es für besser halten den Widgets eine Verstecken und Zeigen Funktion zu geben und dann referenzzählende Smartpointer einzusetzen.
-
Was heisst, du must bei deiner programminternen Registry Klassen, die sich Unreggen auch gleich deleten.
-
Ben04 schrieb:
@otze bei GUIs halte ich die Anwendung von delete this für schlecht und ich bin mir ziehmlich sicher, dass da der Fehlerteufel wüten wird, spätestens wenn Ausnahmen fliegen.
da ein dtor eh keine exception werfen darf, seh ich grad nicht das mögliche fehlerpotential.
Ich würde es für besser halten den Widgets eine Verstecken und Zeigen Funktion zu geben und dann referenzzählende Smartpointer einzusetzen.
kannst du, hilft aber sicher nicht in jeder situation.
-
ein objekt, das sich selbst zerstört, ist wirklich keine gute idee. es sollte von dem programmteil zerstört werden, der es erzeugt hat.
und was die update-sache angeht, da sehe ich zwei möglichkeiten:
-
dein programm ruft regelmäßig die update-methode auf
dann braucht update() nur einen bool-wert zurückzugeben, der dem aufrufenden programm mitteilt, ob das objekt zerstört werden will. oder umgekehrt: was passiert, wenn die update-methode aufgerufen wird, aber das objekt sich bereits selbst zerstört hat? -
die update-methode wird von einem separaten thread aufgerufen. dann lass das objekt vom thread erzeugen und wieder zerstören. ansonsten gilt das selbe wie in (1).
-
-
Das Problem das ich mit sich selbst zerstörenden Objekten habe ist, dass es entweder der Selbstmord gar nicht nötig ist oder es nur über Selbstmord zerstörbar ist.
Beispiel: Wir haben ein Widget das sich bei anderen Widgets abmeldet und anschließend selbst zerstört. Das Abmelden kann eine Exception werfen. Da wir ja davon ausgehen, dass jedes sich zerstörendes Widgets sich auch abmeldet (ansonsten bräuchten wir keinen Selbstmord und könnten Abmeldung von Zerstörung trennen) können wir es nicht mehr einfach deleten weil das nicht vorgesehen ist. Da die Abmeldefunktion werfen kann, haben wir keine Funktion die im Fall eines Stackunwindings das Objekt zerstören könnte. Sprich wir können es nicht mehr an den Stack binden.
Ich will jetzt nicht so weit gehen zu sagen, dass es nicht mehr möglich ist das ausnahmesicher zu machen allerdings sind die Mittel die gebraucht werden würden recht unorthodox und daher fehleranfällig.
Vielleicht hattest du auch einen anderen Anwendungsfall im Kopf an den ich nicht gedacht habe allerdings bin ich bis jetzt fest davon überzeugt, dass delete this mehr Probleme schafft als es löst.
-
-someone- schrieb:
Sprich: Ich muss das Objekt dynamisch erzeugen (und nicht auf dem Stack, wie in meinem Beispiel). Danke!
Und um das zu erzwingen, setzt man den Destruktor protected.