2009-06-24 4 views
1

Mögliche Duplizieren:
Should objects delete themselves in C++?Wann ist es angebracht, "delete this" zu verwenden?

In meiner Anwendung, ich bin viele Objekte zu schaffen, dass „besitzt selbst“ - in dem Sinne, dass, nachdem sie erstellt werden und gesagt, „gehen“, nur Das Objekt selbst kann feststellen, wann es gelöscht werden sollte.

Zum Beispiel, wenn ich ein Spiel schrieb, könnte ich mehrere Enemy Objekte haben. Nur das Enemy Objekt weiß, wann es sterben sollte.

Als Ergebnis, ich am Ende mit delete this innerhalb einiger der Mitglieder Funktionen innerhalb der Enemy Objekt. Ist das eine schlechte Form? Ist das etwas, was ich vermeiden sollte, und wenn ja, wie kann man mit dieser Art von Situation umgehen?

+2

Dupe von http://stackoverflow.com/questions/522637/should-objects-delete-themelsel-in-c unter vielen anderen –

Antwort

5

Vorsicht ist geboten, wenn zu viele Elementfunktionen eine Selbstlöschung als Nebeneffekt haben, ist es leicht, versehentlich einen Verweis auf das Objekt zu verwenden, nachdem es gelöscht wurde.

Ein Ansatz, um dies zu vermeiden, besteht darin, das Löschen zu verschieben - das heißt, das Objekt auf eine Liste setzen und von der Hauptschleife des Spiels alles auf dieser Liste am Anfang/Ende eines Ticks löschen.

+2

oh, klingt wie Garbage Collection! :-) – Tanktalus

+2

@Tanktalus: Klingt für mich nicht viel nach Garbage Collection, da das Objekt selbst dafür verantwortlich ist, sich selbst zu löschen, wenn etwas Logik erfüllt ist. –

+0

@Paul: Die ursprüngliche Frage klang nicht wie GC. Diese Antwort tut es. Abgesehen davon, dass Sie nicht die Adressen durchsuchen müssen, um herauszufinden, was nicht mehr referenziert wird, fügen Sie sich selbst in die Liste der Daten ein, die beim nächsten verfügbaren Zyklus gesammelt werden sollen. – Tanktalus

0

Abstrakt, ich glaube nicht, dass Sie ein Objekt löschen möchten.

Was möchten Sie tun, erstellen Sie eine Kontrollstruktur, die ein SIGNAL oder eine Nachricht von dem Objekt abruft, dass es Zeit ist zu sterben, in diesem Fall, und die Kontrollstruktur "löscht" oder führt die erforderliche Aktion aus das Objekt.

Auf diese Weise behalten Sie die Kontrolle über das Objekt, das in der Kontrollstruktur vorhanden ist oder nicht, und wenn alles eine zentrale Kontrolleinheit hat, verhindern Sie potentielle Aufrufe gelöschter Objekte.

Auch Remember zu unterscheiden zwischen einem Soldaten "sterben", wie Sie sagen, und ein Objekt wird tatsächlich aus dem Speicher "gelöscht". Der sterbende Teil, das Objekt selbst, kann durch Setzen einer Flagge wie "tot = wahr" erreicht werden. Aber das Löschen des Objekts aus dem Speicher sollte durch die Kontrollstruktur erfolgen, auf die ich mich beziehe.

3

Hängt von der Speicherverwaltungsstrategie ab. Es gibt Fälle, in denen es wirklich Sinn macht und es richtig ist. Zum Beispiel würde das Objekt in einem Referenzzählsystem wie COM eine delete this machen, wenn der Refcount auf Null geht.

0

Es scheint mir seltsam, ich selbst würde jemanden oder etwas bevorzugen, die sie loswerden. Die Angst davor, dass jemand auf das Objekt verweist, ist für mich nur erschreckend. Es scheint auch sehr gut möglich zu sein, dass eine "Kind" -Methode das Objekt auf unbekannte Weise zerstört. Wenn Sie zu einer höheren Methode zurückkehren: Sie arbeiten an einem nicht existierenden Objekt.

Es klingt, als ob Sie das Referenzzählen erfunden haben, vielleicht verwenden Sie explizit das Referenzzählmuster.

Oder haben die Objekte sich selbst zu einer "zu zerstören" -Liste hinzufügen - und Sie haben sich ein Garbage-Collection-System.

0

Solange die Feinde alle Verweise auf sie verwalten (zB Liste der Einheiten, Liste der Einheiten in Gruppen usw.) ist es in Ordnung (und wird oft benutzt).

Aber wenn Sie auf der sicheren Seite sein wollen, sollten die Feinde sich registrieren für einige Zerstörung Routine laufen irgend „sicheren Ort“ in der Programmausführung (für ein Beispiel siehe QObject::deleteLater() in Qt.

0

Sie sie automatisch könnte shared_ptrs auf Objekte verwenden zu haben, bereinigen, wenn keine Verweise auf sie nicht mehr verfügbar sind.

Oder die destructor an der Klasse aufrufen.

+0

soory, mis-clicked ... entfernt down-voice wieder. – Arne

0

um ehrlich zu sein, sollten Sie versuchen, weg zu bleiben von dem. Sie Andernfalls könnte etwas löschen, das von etwas anderem benutzt wird und von havi beendet wird ein wirklich merkwürdiges Ergebnis und wahrscheinlich ein Speicherleck damit.

Ich denke, dass das Objekt seine Ressourcen im Destruktor löschen sollte. Deine Klasse sollte eine andere Klasse benutzen, um zu wissen, wann die Feinde tot sind.

3
For example, if I was writing a game, I might have multiple Enemy 

Objekte. Nur das feindliche Objekt kennt wenn es sterben sollte.

Das feindliche Objekt kann wissen, wann es in einen "toten" Zustand eintritt, ja. Das ist aber nicht unbedingt dasselbe wie "das Objekt sollte gelöscht werden".

Denken Sie an alle anderen Objekte, die einen Bezug darauf haben können? Sie können jederzeit versuchen, eine Funktion auf dem Feindobjekt aufzurufen (etwa TakeDamage()), und wenn das Objekt gelöscht wurde, ohne sie zu informieren, wird es wahrscheinlich zu einem Absturz kommen. Woher wissen sie, dass der Feind, auf den sie schießen, tot ist?

Also das Feind-Objekt weiß, wann es tot ist, aber nicht wann es gelöscht werden sollte. Es besitzt sich nicht.

Wer tut besitzen es dann?

Die Spielwelt kann eine gute Wette sein. Wenn der Feind stirbt, sendet er eine Nachricht an die Spielwelt, die sagt, dass sie tot ist, und die Spielwelt könnte dann dafür verantwortlich sein, sicherzustellen, dass niemand einen Zeiger darauf hält, und schließlich, wenn es sicher ist, Löschen das Objekt.

0

Das/die verweisende (n) Objekt (e) sollten die Löschung durchführen und dies tun, indem sie das Objekt fragen, ob die Bedingungen für das Löschen erfüllt sind. Eine der Bedingungen (abgesehen davon, dass sie aus dem Spiel entfernt werden) ist, wie viele andere Objekte sich noch auf das Objekt beziehen. Dies kann mit der statischen Referenzzählung verfolgt werden. Im Allgemeinen, wenn Sie es sorgfältig schreiben, können Sie es möglicherweise so aufbauen, dass Feinde nur an einer Stelle in Ihrer Spielschleife verfolgt werden. Dieser Ort wird Kollisionen und andere Bedingungen prüfen, und wenn er zum Löschen des Objekts bereit ist, muss er nicht fragen, ob die Löschung in Ordnung ist, weil er weiß, dass es der einzige Client ist, und kann die zugewiesene Ressource sicher dereferenzieren.

Verwandte Themen