Smartpointer, wozu?
-
@DDR-RAM: "shared_ptr" implementiert wie der Name schon sagt "shared ownership". Es gibt viele Situationen wo es mühsam ist einen einzigen "owner" festzulegen, bzw. wo man sogar gezwungen ist manche Objekte sehr lange am Leben zu lassen, bloss weil es in manchen seltenen Fällen sein könnte dass sie noch irgendwo referenziert werden. In solchen Fällen ist es halt sehr praktisch "shared ownership" zu haben. "intrusive_ptr" ist im Prinzip dasselbe, bloss funktioniert "intrusive_ptr" nur wenn im Objekt selbst eine Möglichkeit existiert Referenzen zu zählen. "spared_ptr" kommt ohne das aus, allerdings zahlt man dafür den Preis einer zusätzlichen dynamischen Speicheranforderung.
EDIT: verwenden doch intrusive_ptr. Natürlich kannst du auch eine "linked list" Implementierung eines smart_ptr machen, die dürfte ohne Multithreading sogar schneller sein, mit allerdings sicher langsamer.
Ausser dem was "intrusive_ptr" macht und eben der "linked list" Version wüsste ich aber keine Möglichkeit auf die zusätzliche Speicheranforderung zu verzichten.
-
ich glaube du suchst boost::scoped_ptr
-
hustbaer schrieb:
@DDR-RAM: "shared_ptr" implementiert wie der Name schon sagt "shared ownership". Es gibt viele Situationen wo es mühsam ist einen einzigen "owner" festzulegen, bzw. wo man sogar gezwungen ist manche Objekte sehr lange am Leben zu lassen, bloss weil es in manchen seltenen Fällen sein könnte dass sie noch irgendwo referenziert werden. In solchen Fällen ist es halt sehr praktisch "shared ownership" zu haben.
An library-grenzen?
"intrusive_ptr" ist im Prinzip dasselbe, bloss funktioniert "intrusive_ptr" nur wenn im Objekt selbst eine Möglichkeit existiert Referenzen zu zählen.
Ich werd sowas wahrscheinlich als front-end verwenden.
"spared_ptr" kommt ohne das aus, allerdings zahlt man dafür den Preis einer zusätzlichen dynamischen Speicheranforderung.
Also shared_ptr sind nicht schlechtes, mit weak_ptr zusammen hört sich das fast nach gratis gc an, bei der der Entwickler viel anpassen kann durch den spezifischen finalizer. Für Basisklassenzeiger fände ich es aber auch ganz nett, wenn sie die Fähigkeiten eines shared_ptr hätten, Referenzzählung und finalisierung kann man ja auch irgendwie in dieser Klasse erledigen.
Was macht eigentlich std::auto_ptr?MfG
DDR-RAM
-
#include <memory> #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { auto_ptr<string> a(new string("Hallo!")); cout << "a zeigt auf: " << a.get() << endl; auto_ptr<string> b = a; cout << "a zeigt auf: " << a.get() << endl; cout << "b zeigt auf: " << b.get() << endl; return 0; }Ergebnis:
a zeigt auf: 003212A8 a zeigt auf: 00000000 b zeigt auf: 003212A8auto_ptr gibt immer die Verantwortung weiter, soll heißen es gibt immer nur einen Besitzer. Also das genaue Gegenteil von shared_ptr.
-
auto_ptr dient primär einem einzigen Zweck: als sichere Variante der Rückgabe von dynamisch allokierten Objekten durch Funktionen (oder als Übergabeparameter, falls Ownership transferiert werden soll). Für alles andere gibt es bessere Alternativen. Insbesondere als Klassenmember ist auto_ptr nicht geeignet. Grundsätzlich sollte ohnehin die einfachste Art von Smartpointer, die eine gestellte Aufgabe erfüllen kann, gewählt werden. Das ist im Regelfall scoped_ptr bzw. scoped_array.
-
camper schrieb:
Grundsätzlich sollte ohnehin die einfachste Art von Smartpointer, die eine gestellte Aufgabe erfüllen kann, gewählt werden. Das ist im Regelfall scoped_ptr bzw. scoped_array.
Wobei auto_ptr genauso so einfach ist. Sofern nichts kopiert wird, degeneriert dieser zu einem scoped_ptr.
-
Ich finde bloß den Namen "scoped_ptr" aussagekräftiger. Der Name "auto_ptr" suggeriert mehr als er kann. Ist aber rein psychologisch.

-
groovemaster schrieb:
Wobei auto_ptr genauso so einfach ist. Sofern nichts kopiert wird, degeneriert dieser zu einem scoped_ptr.
Das ist widersprüchlich. Die Fähigkeit, in bestimmter Weise kopierbar zu sein, verliert der auto_ptr ja nicht dadurch, dass man keinen Gebrauch davon macht. Auch z.B. ein intrusive_ptr verhält sich da nicht anders, wenn (hier kommt es wieder) der interne Referenzcounter des Objekts für keinen anderen Zweck genutzt wird. Es kommt wohl darauf an, was man unter einfach subsumieren will. Jedenfalls schweift das etwas vom Thema ab.
-
camper schrieb:
Die Fähigkeit, in bestimmter Weise kopierbar zu sein, verliert der auto_ptr ja nicht dadurch, dass man keinen Gebrauch davon macht.
Das ist richtig. Nur entsteht dabei kein Overhead, wenn die Kopiersemantik nicht genutzt wird. Das meinte ich mit "einfach".
-
DDR-RAM schrieb:
"spared_ptr" kommt ohne das aus, allerdings zahlt man dafür den Preis einer zusätzlichen dynamischen Speicheranforderung.
Also shared_ptr sind nicht schlechtes, mit weak_ptr zusammen hört sich das fast nach gratis gc an, bei der der Entwickler viel anpassen kann durch den spezifischen finalizer.
Oha, Vorsicht. shared_ptr ist weit davon entfernt "gratis" zu sein. Jedesmal wenn du einen nicht-leeren shared_ptr konstuierst oder zerstörst kostet das ein InterlockedIncrement/InterlockedDecrement, und interlocked instructions sind teuer. Alleine das herrumreichen eines shared_ptr by Value ist also schon teuer genug, wobei man das ja noch verhindern kann indem man einfach ne const-ref auf den shared_ptr übergibt.
Aber versteh' mich nicht falsch, ich verwende shared_ptr häufig, einfach weil die Dinger so wahnsinnig praktisch sind. Bei Programmteilen die hoch optimiert sein müssen (weil sie so oft durchlaufen werden) überlege ich mir aber gut ob ich nicht vielleicht auf shared_ptr verzichten kann, oder einen Weg finden wie ich keine Kopien anlegen muss, bzw. eben so wenig wie möglich.