Anwendungszweck von shared_ptr<T>?
-
volkard schrieb:
Sone schrieb:
Ich denke gerade nach, was verkettete Zeiger sein könnten. Fungiert der shared_ptr wie ein Listenknoten, und hält einen Zeiger auf den nächsten
shared_ptr? Dann würde use_count() aber eine lineare Komplexität haben, das ist AFAICS nicht verkraftbar.Da aber in 100 Jahren Informatikgeschichte ausßer zum Debuggen kein use_count() auf shared_pointers benötigt wurde, ist das jetzt nicht wirklich das zwingende Argument.
Hmm, ich habe letztens erst nen Loader für den Texturen geschrieben.
Der hat die Texturen in einen shared_ptr geladen, wenn die Textur nochmal angefordert wurde gabs den shared_ptr zurück.
Sporadisch wurden alle shared_ptr im Loadercache geprüft ob der Loader die letzte Referenz hält (use_count()) und falls ja wurde der ptr gelöscht.Schlechtes Design oder sinnvoller Einsatzzweck?
Was wäre besser?
-
@Ethon das kann man mit weak_ptr verbessern. Ansonsten, generell einen shared_ptr auf eine Textur finde ich nicht schlecht, aber ob man überhaupt noch "manuell" einen Cache dazubauen muss ist dann wieder irgendwie fragwürdig, warum sollte man zwei mal die gleiche Textur laden.
-
Ethon schrieb:
Sporadisch wurden alle shared_ptr im Loadercache geprüft ob der Loader die letzte Referenz hält (use_count()) und falls ja wurde der ptr gelöscht.
Schlechtes Design oder sinnvoller Einsatzzweck?
Was wäre besser?use_count()==17 hattest Du niocht wissen wollen.
Nur use_count()!=0.
Also nur is_used().edit:
Nur use_count()!=1.
Also nur is_other_used().
Auch im Ring mit O(1).
-
§ 20.7.2.2.5/8 schrieb:
[ Note: use_count() is not necessarily efficient. — end note ]
-
Genau für solche Fälle gibts ja
shared_ptr::unique().Aber auch das braucht man recht selten. Ich hab
unique()nur einmal bei einer ziemlich unkonventionellen Ressourcenverwaltung benötigt. Inzwischen ist mir aber klar geworden, dass es in vielen Fällen einfacher geht. Designs mitshared_ptrhaben die Tendenz zu hoher Komplexität und Unklarheit über Besitzverhältnisse.
-
Alles, was ich bisher gehört habe, fällt unter
shared_ptr schrieb:
shared_ptr<const T> als Copy-Optimierung macht auch Sinn (also shared_ptr mit immutable Objekten).
Das macht man zwar nicht häufig, kommt aber von Zeit zu Zeit vor und ist aus meiner Sicht absolut legitim.
-
cooky451 schrieb:
Vielleicht wenn mehrere Threads das gleiche Objekt besitzen?
-
cooky451 schrieb:
cooky451 schrieb:
Vielleicht wenn mehrere Threads das gleiche Objekt besitzen?
Darunter konnte ich mir nur was vorstellen, wenn das Objekt immutable ist.
Könntest du kurz erklären?
-
Angenommen man hat eine Art Cache (also einen Container) von schweren Daten. Jetzt soll ein Thread auf einem der Objekte in dem Cache Operationen ausführen. Dieser Thread arbeitet allerdings nur eine queue an jobs ab, die auch etwas länger sein kann. Man möchte verhindern, dass das Objekt aus dem Speicher gelöscht wird solange der Job darauf noch nicht abgearbeitet ist.
-
* COW Datenstrukturen.
* In Kombination mit weak_ptr: Thread-safe Signals/Slots Implementierungen.
Kellerautomat schrieb:
Ich benutze shared_ptr z.B., um ungenutze Objekte in einen Cache zu werfen (Custom Deleter).
+1
Wobei man sie nicht gleich rauswerfen muss. Man kann sie im Deleter auch nur auf "nicht in Verwendung" setzen.
Und natürlich alle Cache-Ähnlichen Anwendungen wie Pools (Database-Connection Pool, ...).
-
shared_ptr schrieb:
Alles, was ich bisher gehört habe, fällt unter
shared_ptr schrieb:
shared_ptr<const T> als Copy-Optimierung macht auch Sinn (also shared_ptr mit immutable Objekten).
Das macht man zwar nicht häufig, kommt aber von Zeit zu Zeit vor und ist aus meiner Sicht absolut legitim.
Du hast entweder nicht zugehoert und das angesprochene Video nicht angesehen.
-
Ich hab hier shared_ptr im Einsatz um Sets und Subsets für unsere Datensatzklasse zu implementieren (subsets können ihre Eltern überleben)
-
z.B. wie bei uns eine Objektfabrik, die Datensätze aus verschiedenen Tabellen einer Datenbank in Objekte mapped und die erzeugten Objekte als weak_ptr cached.
Die Fabrik gibt die Objekte an ihre Besitzer weiter. Einige Objekte können dabei mehrere "Besitzer" haben. z.B. kann eine Maschinenachse mehrere Funktionen haben oder ein Maschineneinstellung hat mehrere Beobachter, ...
-
Ich habe aktuell zwei Verwendungen vom shared_ptr:
1. Zwei nicht-modale Fenster, die auf die gleichen Daten verweisen (eines davon auch schreibend), und wo die Daten nach dem Schließen gelöscht werden.
2. Als Workaround für einen ansonsten nötigen massiven Umbau in einem älteren Projekt (Vorher Zeigerübergabe, aber es konnte der Fall eintreten, das der Zeiger zwischenzeitlich durch eine Aktualisierung ungültig wurde). Dies ist aber dem etwas verkorksten Design geschuldet.
-
Ich verwende std::shared_ptr<..> im Zusammenhang mit Boost.Asio, wo ich shared_from_this() an die Handler übergebe um die Lebenszeit mindestens solange zu erhalten bis alle Handler completed sind.