2016-05-17 5 views
2

Ich muss einen Smart-Zeiger in einer Karte halten. Die Karte besitzt das Objekt nicht, aber es gibt mehrere shared_ptrs für das Objekt an anderer Stelle.Muster zum bereinigen Smart Ptr aus Container ohne Besitz

Wie kann ich sicherstellen, dass der Schlüssel aus dieser Map entfernt wird, sobald alle anderen shared_ptrs des Objekts zerstört sind, ohne die Map regelmäßig abzurufen?

+2

Wie wäre es. Speichern Sie einen rohen Zeiger in der Karte. Verwenden Sie ein benutzerdefiniertes Löschelement für das shared_ptr, das einen Verweis auf die Zuordnung enthält, und entfernen Sie den Schlüssel/Wert aus der Zuordnung, wenn das benutzerdefinierte Löschprogramm aufgerufen wird. –

+0

Ich habe etwas in diese Richtung gedacht (in meinem Fall könnte ich es einfach im Klassenzerstörer handhaben, da dieses Objekt immer mit einem intelligenten ptr versehen wird), aber ich frage mich, ob es ein allgemein vorgeschriebenes Muster dafür gibt, da das Problem scheint nicht so selten zu sein. Vielen Dank. – Kindread

Antwort

2

Wenn Sie "ohne Polling" meinen, dass Sie möchten, dass std::shared_ptr alles für Sie behandelt, dann wissen Sie, dass dies kein Merkmal von std::shared_ptr ist. True, ein shared_ptr weiß über seine aktuelle Nutzungszahl, aber es empfängt keine Signale, um es von irgendwelchen Änderungen zu aktualisieren.

Sie können jedoch eine Lösung haben, die manchmal, aber nicht die ganze Zeit Prüfungen durchführt.

Ich würde vorschlagen, eine std::map, die std::weak_ptr statt std::shared_ptr enthält. Sie müssen einen Check durchführen, um zu sehen, welche Ptrs ungültig sind, und sie entfernen. Wie oft es zu überprüfen ist, hängt von Ihnen ab. Sie können beispielsweise Ihre Karte nur überprüfen, wenn Sie ein neues Objekt hinzufügen und mehr als 20.000 Objekte in Ihrer Karte vorhanden sind.

+0

Es gibt Möglichkeiten, wie ich es tun kann, mit dem Destruktor oder einem benutzerdefinierten Deleter. Ich habe es nicht in Erwägung gezogen, die Karte anhand der Größe und nicht nach einem bestimmten Zeitintervall zu überprüfen, danke dafür. – Kindread

+0

Wenn Sie mit dieser Lösung gehen, dann ist es wichtig, sicherzustellen, dass Sie std :: weak_ptr anstelle von std :: shared_ptr verwenden, sonst werden Sie nur Speicherplatz freigeben, wenn Sie Ihre Karte reinigen, die nicht oft sein kann. –

+1

@Kindread Die Verwendung eines Destruktors/benutzerdefinierten Löschprogramms ist eine Möglichkeit, dies zu tun, solange Sie mit Ihrer Karte vertraut sind. –