Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Instanz aus sich selbst löschen
Flamefire - Mi 04.08.10 12:06
Titel: Instanz aus sich selbst löschen
Hab folgende Situation:
Eine Instanz Foo wird von der instanz Bar in einer Objektliste gehalten.
Wenn ich jetzt Foo löschen will, muss ich Bar.Delete(Foo.ID) aufrufen, dass dan den eintrag aus der Objektliste entfernt und Foo freigibt.
Was würde passieren, wenn der Aufruf mittels Foo kommt?
Also Foo.Delete() --> Bar.Delete(Self.ID)
Ich gebe ja die Instanz frei, aber muss trotzdem in die Prozedur zurückspringen, da ich ja von dort aufgerufen habe.
Testen bringt nix. Würde vermutlich funktionieren, weil grad nix andres den Speicher genommen hat. Aber kann ja dann doch ungünstige Situationen geben.
Oder funktioniert das doch, weil der Code des Objekts bei Instantiierung nicht kopiert, sondern einfach verwendet wird?
So dass die einzige Beschränkung, die ich habe, ist, dass ich nicht euf Eigenschaften zugreifen kann. Also nach Bar.Delete(Self.ID) aufruf meine Self.ID zurückgeben o.ä.
elundril - Mi 04.08.10 16:08
und das freigeben kannst du nicht in die unterklasse verschieben? Also das du in foo.delete() dann einfach self.free; aufrufst? (nur so ne idee getestet hab ich noch nie)
Flamefire - Mi 04.08.10 16:39
genau das ist die frage. kann ich mehr oder weniger direkt "self.Free" verwenden, oder macht er probleme, da ich ja in der methode noch in der instanz drin bin.
Flamefire - Mi 04.08.10 17:24
vcl ok. da hängt ja alles noch in eventhandlern.
aber ich glaube, dass methoden eines objekts nur einmal vorhanden sind und beim aufruf ein pointer auf das objekt kriegen.
wenn ich nach dem free nicht mehr auf eigenschaften (also den pointer) zugreife, sollte alles laufen.
aber da gehts mir halt mal um ne bestätigung
jaenicke - Mi 04.08.10 19:18
Vorweg: Überlege dir lieber eine bessere Architektur. Das lässt sich garantiert sinnvoller lösen.
Aber zur Frage: Da es sich ja um eine eigene Klasse handelt, funktioniert das. Einfach weil eine Klasse von sich aus nicht mehr auf sich selbst zugreift. (Siehe Assemblerquelltext. ;-))
Allerdings musst du auf referenzgezählte Sachen wie Interfaces achten. Wenn du noch einen Zeiger auf ein Interface offen hast, dessen Objekt durch das Free freigegeben wird, ist das z.B. schlecht. ;-)
Dennoch gehört die Logik ein Element zu löschen eigentlich nicht in das Objekt hinein. Wenn, dann kann das zurückmelden, dass es gelöscht werden möchte. Aber dann macht das die Klasse, die die Elemente steuert und nicht umgekehrt.
Flamefire - Mi 04.08.10 20:25
Nja es geht halt darum, dass ich Nachrichten habe. Die sind in einer Box. Beides sind Klassen, so dass ich mehrere machen kann, wie ich die halt brauche. Bzw sind die Boxen Objektlisten in einer Klasse.
Und mir scheint es zu umständlich, wenn ich eine PN schon aus der Box rausgesucht und damit irgendwas gemacht habe, dann noch Box.Delete(PN.ID) oder vl noch PN.Box.Delete(PN.ID) aufrufen zu müssen.
Viel besser ist da doch ein PN.Delete()
Was intressiert mich beim Löschen denn die Box, in der die mal war?
jaenicke - Mi 04.08.10 20:55
Ich stell mir das gerade so vor, wie der Chef über die Personalabteilung einen Mitarbeiter heraussucht, der gekündigt werden soll und dann dem Mitarbeiter sagt er soll sich bitte kündigen. ;-)
Von der Logik her ist deine Box dafür zuständig. Aber wie gesagt, solange du ein wenig drauf schaust was du mit Referenzzählung benutzt (oder die z.B. bei Interfaces durch überschreiben von _Release usw. herausnimmst), klappt es auch wie du es möchtest.
elundril - Mi 04.08.10 20:58
jaenicke hat folgendes geschrieben : |
| Ich stell mir das gerade so vor, wie der Chef über die Personalabteilung einen Mitarbeiter heraussucht, der gekündigt werden soll und dann dem Mitarbeiter sagt er soll sich bitte kündigen. ;-) |
Als Chef muss man delegieren können :mrgreen:
delfiphan - Do 05.08.10 07:06
Flamefire hat folgendes geschrieben : |
Oder funktioniert das doch, weil der Code des Objekts bei Instantiierung nicht kopiert, sondern einfach verwendet wird?
So dass die einzige Beschränkung, die ich habe, ist, dass ich nicht euf Eigenschaften zugreifen kann. Also nach Bar.Delete(Self.ID) aufruf meine Self.ID zurückgeben o.ä. |
Exakt so sieht's aus. Solange du nicht aus Felder des Objektes oder Self zugreifst, wird dir das technisch keine Probleme bereiten.
Architektonisch gesehen würde ich eher eine Notification im Destruktor schmeissen. Bar muss dann das Objekt aus der Objektliste löschen, ohne zu versuchen, das Objekt freizugeben (siehe Exktract in TObjectList). Statt Foo.Delete würde man dann Foo.Free schreiben, was klarer ist.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!