PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Reference Counting Pointer


Benutzernamen
2007-09-24, 14:03:02
Mahlzeit

Ich habe ein Objekt (ich glaube man nennt es Fabrik), daß mit einer static Methode und einem Parameter ein Objekt baut, es zurückleifert und es in einer Liste speichert - sollte jemand anders auch dieses Objekt wollen [und das wird passieren], wird es aus der Liste (std::map) zurückgeliefert. Niemand anders sonst kann ein Objekt dieser Art erzeugen.

Die Idee dahinter ist, daß sich an verschiedenen Stellen Klassen ein spezielles Objekt holen können und sichergestellt wird, daß sie dann auf der gleichen Instanz arbeiten.

Nur ist das noch etwas schwierig festzustellen, wann keine Klasse das Objekt mehr benötigt und es gelöscht werden kann. Am Horizont habe ich schonmal von SmartPointern gehört, bin aber nicht sicher wie das hier funktionieren kann - weil in der std::map sind ja auch noch Referenzen.

Jemand eine Idee, wie man das macht?

Bietchiebatchie
2007-09-24, 15:04:18
Ich glaube ohne "Abmelden" (also der Fabrik mitteilen, das das Objekt nicht mehr gebraucht wird) läuft da nix.
Das einfachste was mir da einfällt, ist einfach nicht nur das Objekt in der Fabrik zu speichern, sondern auch einen Counter für jedes erstellte Objekt. Damit hat die Fabrik zwei Methoden:
- Create(parameter) : Objekt
- Destroy(Objekt) : void
Create erstellt das Objekt, falls bisher nicht geschehen und inkrementiert den Counter.
Destroy dekrementiert den Counter, falls dieser gleich 0 ist, wird das Objekt gelöscht.

Chris Lux
2007-09-24, 16:14:51
Ich glaube ohne "Abmelden" (also der Fabrik mitteilen, das das Objekt nicht mehr gebraucht wird) läuft da nix.
Das einfachste was mir da einfällt, ist einfach nicht nur das Objekt in der Fabrik zu speichern, sondern auch einen Counter für jedes erstellte Objekt. Damit hat die Fabrik zwei Methoden:
- Create(parameter) : Objekt
- Destroy(Objekt) : void
Create erstellt das Objekt, falls bisher nicht geschehen und inkrementiert den Counter.
Destroy dekrementiert den Counter, falls dieser gleich 0 ist, wird das Objekt gelöscht.
warum nicht einfach in den destructor der klasse, welche auch referenz gezaehlt wird, einbauen, dass wenn der refcount gleich 0 wird sich bei der factory abgemeldet wird...

Neomi
2007-09-24, 22:44:40
warum nicht einfach in den destructor der klasse, welche auch referenz gezaehlt wird, einbauen, dass wenn der refcount gleich 0 wird sich bei der factory abgemeldet wird...

Schlechte Idee, sehr schlechte Idee. Wenn der Destruktor aufgerufen wird, wird das Objekt bereits zerstört.

Allgemein ist das IUnknown-Interface eine recht gute Vorlage, wenn es schon um C++ geht. IUnknown::AddRef() inkrementiert den Reference Counter, IUnknown::Release() dekrementiert ihn und löscht das Objekt, wenn der Counter 0 erreicht.

Coda
2007-09-24, 23:48:37
Wieso ist das eine schlechte Idee? Die member der Klasse werden erst freigegeben nachdem der Destructor durchgelaufen ist und this ist auch noch valid.

Neomi
2007-09-25, 00:23:10
So gesehen ist das durchaus sinnvoll, das habe ich dann wohl eben falsch interpretiert.

Ich hatte den Ansatz von Chris Lux vorhin so verstanden, daß der Reference Counter im Destruktor runtergezählt werden soll, der sich dann im Fall 0 erst tatsächlich löscht (was ja so nicht funktionieren würde) und jeder Referenzhalter einfach mal versucht, das Objekt zu löschen. Das wäre eine sehr schlechte Idee gewesen, aber das wahr ja offenbar doch nicht die Idee.

Daß über eine Release()-Methode (oder wie auch immer die dann genannt wird) in letzter Konsequenz der Destruktor einmalig aufgerufen wird und der das Objekt dann bei der Factory abmeldet, ist ein guter Ansatz.

Benutzernamen
2007-09-27, 08:39:37
Danke. Muß sagen, daß ich dies auch noch nicht so ganz verstehe. Wie wird denn der Destruktor aufgerufen ohne das ein Objekt zerstört wird?

Die Idee mit diesen Release() Methoden auf dem Objekt ging dahin die Factory darüber anzusprechen und sich dort abzumelden, wenn 0 erreichet wird? Schützt einen was davor, daß ein Release() evtl. mal versehentlich 2x o.ä. aufgerufen wird?