2010-05-25 7 views
7

boost::intrusive_ptr erfordert intrusive_ptr_add_ref und intrusive_ptr_release definiert werden. Warum wird keine Basisklasse zur Verfügung gestellt, die dies tun wird? Es gibt ein Beispiel hier: http://lists.boost.org/Archives/boost/2004/06/66957.php, aber das Poster sagt "Ich denke nicht unbedingt, dass dies eine gute Idee ist". Warum nicht?intrusive_ptr: Warum wird keine allgemeine Basisklasse bereitgestellt?

Update: Ich glaube nicht, dass die Tatsache, dass diese Klasse mit Mehrfachvererbung missbraucht werden könnte, Grund genug ist. Jede Klasse, die von mehreren Basisklassen mit ihrer eigenen Referenzzahl abgeleitet ist, würde das gleiche Problem haben. Ob diese Refcounts über eine Basisklasse implementiert werden oder nicht, macht keinen Unterschied.

Ich glaube nicht, dass es ein Problem mit Multithreading gibt; boost::shared_ptr bietet atomare Referenzzählung und diese Klasse könnte auch.

+3

über einen entsprechenden Hinweis, 'osg :: ref_ptr' aus der Open Bibliothek verwendet eine Top-Level gemeinsame Basisklasse (: Es kann sowohl für Thread-sicher oder faden unsicher Refcounting konfiguriert werden 'osg :: Referenced') für seine intrusive Smart-Pointer-Implementierung. –

+3

Und osg :: Referenced ist kompatibel mit boost :: intrusive_ptr, da es die Funktionen intrusive_ptr_add_ref() und intrusive_ptr_release() zur Verfügung stellt. Funktioniert perfekt. –

Antwort

2

Boost bietet eine Möglichkeit dafür.

#include <boost/intrusive_ptr.hpp> 
#include <boost/smart_ptr/intrusive_ref_counter.hpp> 

class CMyClass 
    : public boost::intrusive_ref_counter< 
           CMyClass, 
           boost::thread_unsafe_counter> 
    ... 

boost::intrusive_ptr<CMyClass> myPtr; 

http://www.boost.org/doc/libs/1_62_0/libs/smart_ptr/intrusive_ref_counter.html

+0

Mit anderen Worten die Antwort auf meine Frage lautet: "Es sollte, und jetzt gibt es" :) – Jon

+0

Sieht so aus, als wäre es eine Weile dort gewesen, aber hat sich ein bisschen bewegt. Hier ist der erste Dokumentverweis, den ich gefunden habe: http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/utilities.html#header.boost.log.utility.intrusive_ref_counter_hpp –

3

Das Problem wäre mit Mehrfachvererbung. Wenn Sie von 2 Objekten erben, die diese Basis implementieren, dann haben Sie 2 Zähler für Ihr einzelnes Objekt ... und das könnte Chaos verursachen.

Also müssen Sie die ptr_add und die Methoden ptr_release virtuell machen, so dass die abgeleitete Klasse eine Überschreibung implementieren kann, um die mehreren Zähler auf einmal zu synchronisieren ... Einige Leistungseinbußen hier, vor allem seit den meisten Zeiten völlig unnötig (es würde keine Überschreibung geben), weil es nur für die Mehrfachvererbung nützlich ist.

Und natürlich in Multi-Threaded-Umgebungen könnten Sie (für kurze Zeit) desynchronisierte Zähler (die erste wurde inkrementiert, aber der Thread wurde unterbrochen, bevor die zweite war) kann ich noch nicht von irgendeinem Problem denken Ursache, aber es ist keine gesunde Situation.

Sie fügen auch der Klasse Clutter hinzu, einige Clients benötigen möglicherweise keine Referenzzählung (wenn sie das Objekt auf dem Stapel erstellen).

Ich denke, es ist keine gute Idee;)

+2

Mehrfachvererbung: Dieses Problem tritt auch auf, wenn Sie über zwei Basisklassen verfügen, die ihre eigene Referenzanzahl implementieren. Ob dieser Refcount über eine Basisklasse implementiert wird oder nicht, spielt keine Rolle. Multi-Threaded: shared_ptr hat Atom-Inkrement/Dekrement, also könnte diese Klasse auch. "Einige Clients brauchen möglicherweise keine Referenzzählung": das ist ein Grund, warum Sie intrusive_ptr nicht verwenden würden, nicht warum es keine Basisklasse gibt. – Jon

+1

@ Jon: Ich stimme der Mehrfachvererbung zu, in der Tat können Sie intrusive Referenzzählung ohne eine Basisklasse implementieren. Allerdings stimme ich den beiden anderen Bemerkungen nicht zu: für MT 'shared_ptr' liefert die atomare Semantik leicht, da es nur einen Zähler hat, wenn Sie mehrere Zähler in einem kohärenten Zustand halten müssen, dann müssen Sie explizit sperren (keine atomaren Ops mehr verfügbar) und Das bedeutet konsequente Overhead ... folgen Sie dem weißen Kaninchen ... –

+1

Für den 'intrusive_ptr'-Teil: Ich bin hier partiell, aber ich dachte immer, dass der intrusive Ansatz in dem Sinne "falsch" war, dass er sowohl eine "funktionale" Klasse als auch ein "Management" -Verhalten bündelte. Das ist also effektiv eine Kritik am intrusiven Referenzzählmechanismus. Ich finde den 'shared_ptr'-Ansatz hier fester, und die Tatsache, dass Sie nicht versehentlich zwei Zähler für einen einzelnen Satz von' shared_ptr' haben können, ist ein netter Bonus. –

4

Es ist so können Sie intrusive_ptr mit Klassen verwenden, hinzufügen und die Freigabe bereits implementieren.

+0

Es gibt andere Gründe für die Verwendung von intrusive_ptr (Speicherabdruck, Leistung, Konstruieren aus beliebigen rohen Pointern) – Jon

+0

Es ist der beste Grund, obwohl IMHO –

Verwandte Themen