MyDeleter schrieb:
Ja, das war der Tatsache geschuldet, dass ich ein Minimal-Beispiel schreiben wollte :). Eigentlich ist der Deleter dann im ReferenceCounter-Objekt untergebracht.
Für nen unique_ptr brauchst du kein ReferenceCounter-Objekt
MyDeleter schrieb:
Ich hatte auch schon gelesen, dass der unique_ptr im Vergleich zu einem Raw-Pointer keinen Overhead hat. Aber warum hat man sich dann beim shared_ptr dazu entschieden eine andere Deleter Syntax als beim unique_ptr zu verwenden, wenn es gar keinen Vorteil bringt.
Natürlich bringt es einen Vorteil. z.B. dass bei shared_ptr der Typ vom Deleter nicht den Typ des Smartpointers beeinflusst. Es ist immer shared_ptr<T> , ganz egal was für einen Deleter man verwendet.
MyDeleter schrieb:
Im Gegenteil sogar langsamer ist (Deleter lookup),
Hast du das gemessen? Der einzige Overhead den ich sehen kann (in der Boost Implementierung) ist ein virtual-call. Den könnte man natürlich loswerden, wenn man sich die Typ-Abhängigkeit eintreten möchte, und den damit einhergehenden Template-Bloat.
MyDeleter schrieb:
mehr Speicher braucht
Wieder: Hast du das gemessen? Wüsste nicht wieso es mehr Speicher brauchen sollte. Bei shared_ptr brauchst du den Control-Block (="ReferenceCounter-Objekt") sowieso. Da noch den Deleter mit reinzustopfen sollte, wenn man es richtig macht (Empty-Base und so), keinen Unterschied machen.
Weiters wäre es etwas seltsam wenn man den Deleter in jedem Zeiger vorhält (kann ja bei Shared-Ownership mehrere geben die auf das selbe Objekt zeigen). Und auch einiges an Overhead (falls der Deleter nicht "leer" ist). Und es ergeben sich noch ganz andere Probleme. z.B. kann shared_ptr das Objekt immer "passend" löschen, selbst wenn es ein Polymorphes Objekt mit nicht-virtuellem Destruktor in der Basisklasse ist, und der letzte shared_ptr der das Objekt löscht ein shared_ptr<Basisklasse> ist. Eben weil der Deleter mit im Control-Block drinnen steckt, und dieser auf den Typ des Objekts spezialisiert ist mit dem der shared_ptr ursprünglich initialisiert wurde. Versuch das mal mit einer "Overhead-freien" Implementierung hinzubekommen die den Deleter direkt in der Zeiger-Instanz speichert.
MyDeleter schrieb:
und der Code auch noch unschöner ist.
Welcher Code soll unschöner als was sein
MyDeleter schrieb:
Ich denke dann werde ich den Gedanken verwerfen, den Deleter im ReferenceCounterObjekt zu teilen und den Deleter über die Empty Base Class Optimisation versuchen zu implementieren.
Wenn du keine Shared-Ownership brauchst, dann nimm einfach unique_ptr . Bzw. implementiere selbst etwas was ganz ohne Control-Block auskommt, wenn du es unbedingt selbst implementieren willst. Und wenn du doch Shared-Ownership brauchst, dann finde ich den Tradeoff von shared_ptr durchaus sinnvoll. Es vermeidet Template-Bloat und der Overhead ist IMO durchaus akzeptabel. Vor allem da das Löschen/Resetten eines shared_ptr sowieso schon zumindest eine CAS Instruktion braucht (und die sind üblicherweise nicht gerade die schnellsten).