<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[factory + smart pointer]]></title><description><![CDATA[<p>hallo,</p>
<p>ich habe folgenden code:</p>
<pre><code class="language-cpp">class base { public: typedef base* ptr; };
class derived : public base { public: typedef derived* ptr; };

class base_factory {
	public: virtual base::ptr create_obj() = 0;
};

class derived_factory : public base_factory {
	public : derived::ptr create_obj() { return derived::ptr(new derived()); }
};
</code></pre>
<p>das kompiliert und funktioniert wie gewünscht, denn jedes derived* ist auch ein base*.</p>
<p>zu dem new muss jetzt natürlich noch das passende delete dazu.<br />
ich dachte mir, dass boost::shared_ptr hier gut geeignet wäre, um dem benutzer das explizite löschen zu ersparen:</p>
<pre><code class="language-cpp">class base { public: typedef boost::shared_ptr&lt;base&gt; ptr; };
class derived : public base { public: typedef boost::shared_ptr&lt;derived&gt; ptr; };
</code></pre>
<p>das kompiliert so aber nicht mehr.</p>
<blockquote>
<p>error C2555: 'derived_smart_factory::create_obj': overriding virtual function return type differs and is not covariant from 'base_smart_factory::create_obj'</p>
</blockquote>
<p>ein boost::shared_ptr&lt;derived&gt; ist also leider kein boost::shared_ptr&lt;base&gt;.</p>
<p>ist shared_ptr hierfür ungeeignet? wie ginge es besser?<br />
es wäre wichtig, dass derived_factory nicht nur ein derived erzeugt, sondern auch den richtigen typ liefert, damit ich nachher nicht rumcasten muss, wenn ich spezielle funktionen von derived aufrufe. ich möchte es außerdem nur ungern dem user überlassen, das erzeugte objekt wieder zu löschen.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/213806/factory-smart-pointer</link><generator>RSS for Node</generator><lastBuildDate>Tue, 13 Oct 2026 21:53:40 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/213806.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 22 May 2008 11:31:41 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 11:31:41 GMT]]></title><description><![CDATA[<p>hallo,</p>
<p>ich habe folgenden code:</p>
<pre><code class="language-cpp">class base { public: typedef base* ptr; };
class derived : public base { public: typedef derived* ptr; };

class base_factory {
	public: virtual base::ptr create_obj() = 0;
};

class derived_factory : public base_factory {
	public : derived::ptr create_obj() { return derived::ptr(new derived()); }
};
</code></pre>
<p>das kompiliert und funktioniert wie gewünscht, denn jedes derived* ist auch ein base*.</p>
<p>zu dem new muss jetzt natürlich noch das passende delete dazu.<br />
ich dachte mir, dass boost::shared_ptr hier gut geeignet wäre, um dem benutzer das explizite löschen zu ersparen:</p>
<pre><code class="language-cpp">class base { public: typedef boost::shared_ptr&lt;base&gt; ptr; };
class derived : public base { public: typedef boost::shared_ptr&lt;derived&gt; ptr; };
</code></pre>
<p>das kompiliert so aber nicht mehr.</p>
<blockquote>
<p>error C2555: 'derived_smart_factory::create_obj': overriding virtual function return type differs and is not covariant from 'base_smart_factory::create_obj'</p>
</blockquote>
<p>ein boost::shared_ptr&lt;derived&gt; ist also leider kein boost::shared_ptr&lt;base&gt;.</p>
<p>ist shared_ptr hierfür ungeeignet? wie ginge es besser?<br />
es wäre wichtig, dass derived_factory nicht nur ein derived erzeugt, sondern auch den richtigen typ liefert, damit ich nachher nicht rumcasten muss, wenn ich spezielle funktionen von derived aufrufe. ich möchte es außerdem nur ungern dem user überlassen, das erzeugte objekt wieder zu löschen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514214</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514214</guid><dc:creator><![CDATA[fabrikarbeiter]]></dc:creator><pubDate>Thu, 22 May 2008 11:31:41 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 11:52:19 GMT]]></title><description><![CDATA[<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>hallo,</p>
<p>ich habe folgenden code:</p>
<pre><code class="language-cpp">class base { public: typedef base* ptr; };
class derived : public base { public: typedef derived* ptr; };

class base_factory {
	public: virtual base::ptr create_obj() = 0;
};

class derived_factory : public base_factory {
	public : derived::ptr create_obj() { return derived::ptr(new derived()); }
};
</code></pre>
<p>das kompiliert und funktioniert wie gewünscht, denn jedes derived* ist auch ein base*.</p>
</blockquote>
<p>Irgendwie glaube ich nicht, dass das so kompiliert. In Deiner derived_factory passt der Rückgabetyp von create_obj() nicht. Daher ist derived_factory auch so erstmal keine base_factory.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514226</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514226</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 22 May 2008 11:52:19 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 11:56:10 GMT]]></title><description><![CDATA[<p>warum nicht einfach einen normalen zeiger zurueck geben?<br />
der anwender kann dann ja eh immer smartpointer verwenden.</p>
<p>denn smartpointer - vorallem shared_ptr sind nicht immer sinnvoll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514230</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514230</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 22 May 2008 11:56:10 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:17:45 GMT]]></title><description><![CDATA[<p>hallo</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>warum nicht einfach einen normalen zeiger zurueck geben?</p>
</blockquote>
<p>weil ein shared_ptr für meine situation sehr gut passen und das interface vereinfachen würde.</p>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Irgendwie glaube ich nicht, dass das so kompiliert.</p>
</blockquote>
<p>da glaubst du falsch. das nennt sich &quot;covariant return types&quot; und ist teil des c++-standards.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514248</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514248</guid><dc:creator><![CDATA[fabrikarbeiter]]></dc:creator><pubDate>Thu, 22 May 2008 12:17:45 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:44:49 GMT]]></title><description><![CDATA[<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>hallo</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>warum nicht einfach einen normalen zeiger zurueck geben?</p>
</blockquote>
<p>weil ein shared_ptr für meine situation sehr gut passen und das interface vereinfachen würde.</p>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Irgendwie glaube ich nicht, dass das so kompiliert.</p>
</blockquote>
<p>da glaubst du falsch. das nennt sich &quot;covariant return types&quot; und ist teil des c++-standards.</p>
</blockquote>
<p>Jo, hast recht. Der Compiler, mit dem ich mich hier rumquälen muss ist nur zu alt und schrottig. Der kann das noch nicht.</p>
<p>Dann vielleicht so:</p>
<pre><code class="language-cpp">class base { public:  };
class derived : public base { public: };

class base_factory 
{
protected: 
    virtual base* create_obj() = 0;
public:
    boost::shared_ptr&lt;base&gt; create()
    {
        return boost::shared_ptr&lt;base&gt;(create_obj());
    }
};

class derived_factory : public base_factory 
{
protected:
    virtual derived* create_obj()
    {
        return new derived();
    }
public : 
    boost::shared_ptr&lt;derived&gt; create()
    {
        return boost::shared_ptr&lt;derived&gt;(create_obj());
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1514254</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514254</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 22 May 2008 12:44:49 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:22:45 GMT]]></title><description><![CDATA[<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>hallo</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>warum nicht einfach einen normalen zeiger zurueck geben?</p>
</blockquote>
<p>weil ein shared_ptr für meine situation sehr gut passen und das interface vereinfachen würde.</p>
</blockquote>
<p>Und ich dachte der Thread geht darueber dass shared_ptr eben nicht passt weil es damit keine covariant return types gibt.</p>
<p>wie man sich irren kann...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514255</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514255</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 22 May 2008 12:22:45 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:24:03 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>warum nicht einfach einen normalen zeiger zurueck geben?</p>
</blockquote>
<p>Weil bei einem Zeiger nicht immer sicher gestellt ist, wie er verwaltet wird. Wenn ich mit shared_ptr arbeite kann ich auch die Factory so umstellen das sie intern mit einem Cache arbeitet, ohne die Schnittstelle zu ändern.</p>
<p>Ja, man kann es mit Smartpointern auch übertreiben (wobei ich hier lieber übertreibe wenn ich dafür ein stabiles Programm habe - optimieren kann man immer noch), aber sie haben den entschiedenen Vorteil das die Speicherverwaltung geklärt ist.</p>
<p>@fabrikarbeiter<br />
boost::shared_ptr&lt;base&gt; ist ein anderer Typ as boost::shared_ptr&lt;derived&gt;.<br />
Der Sinn einer solchen Fabrik ist aber das der Typ nicht entscheidend ist (Polymorphie) - sprich eigentlich wäre die Rückgabe von boost::shared_ptr&lt;base&gt; richtig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514259</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514259</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 22 May 2008 12:24:03 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:26:31 GMT]]></title><description><![CDATA[<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Irgendwie glaube ich nicht, dass das so kompiliert.</p>
</blockquote>
<p>da glaubst du falsch. das nennt sich &quot;covariant return types&quot; und ist teil des c++-standards.</p>
</blockquote>
<p>Nein, ist es nicht. Nicht so wie du es anwendest.</p>
<p>base* und derived* sind hierbei &quot;covariant return types&quot;</p>
<p>shared_ptr&lt;base&gt; und shared_ptr&lt;derived&gt; sind es aber nicht! Diese beiden Typen haben nichts miteinander gemeinsam.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514263</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514263</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 22 May 2008 12:26:31 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:37:15 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Irgendwie glaube ich nicht, dass das so kompiliert.</p>
</blockquote>
<p>da glaubst du falsch. das nennt sich &quot;covariant return types&quot; und ist teil des c++-standards.</p>
</blockquote>
<p>Nein, ist es nicht. Nicht so wie du es anwendest.</p>
<p>base* und derived* sind hierbei &quot;covariant return types&quot;</p>
<p>shared_ptr&lt;base&gt; und shared_ptr&lt;derived&gt; sind es aber nicht! Diese beiden Typen haben nichts miteinander gemeinsam.</p>
</blockquote>
<p>Jo, aber mit dem Workaround, den ich oben gepostet habe, kann man das evtl. umgehen. Ich kanns hier leider nicht testen, weil ich a) kein Boost installiert habe und b) mein Compiler nicht mit kovarianten Rückgabewerten klar kommt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514272</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514272</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 22 May 2008 12:37:15 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:43:52 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Weil bei einem Zeiger nicht immer sicher gestellt ist, wie er verwaltet wird. Wenn ich mit shared_ptr arbeite kann ich auch die Factory so umstellen das sie intern mit einem Cache arbeitet, ohne die Schnittstelle zu ändern.</p>
</blockquote>
<p>Das wuerde mich aber mal interessieren. Wie sollte sowas aussehen? Mehrmals die selbe instanz liefern? Das waere aber mal sehr boese.</p>
<p>Man kann auch nicht definieren wie der Pointer zerstoert werden soll, denn dann muesste man das interface aendern.</p>
<p>Es geht hier rein um ein automatisches delete und das kann der user genauso setzen. oft ist ein scoped_ptr sinnvoller als ein shared_ptr...</p>
<p>shared_ptr liefern hier eben den grund fuer das problem. Da base und dervied shared_ptr keine verwandten typen sind. welchen nachteil habe ich, wenn ich einen normalen zeiger zurueck liefere?</p>
<p>ich habe den vorteil der covariant return types und die flexibilitaet jeden smart pointer zu verwenden den der user verwenden will.</p>
<p>das sind 2 vorteile: welchen nachteil habe ich? der user kann sich gegen die verwendung von smart pointern entscheiden. das ist alles.</p>
<p>PS:<br />
der workaround wuerde natuerlich funktionieren, aber es ist einfach unpraktisch x&lt;base&gt; mit x&lt;derived&gt; zu mischen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514275</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 22 May 2008 12:43:52 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:47:39 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>PS:<br />
der workaround wuerde natuerlich funktionieren, aber es ist einfach unpraktisch x&lt;base&gt; mit x&lt;derived&gt; zu mischen...</p>
</blockquote>
<p>Tut man ja nicht. Man wird nur gezwungen, Smartpointer zu benutzen. Ansonsten ist es kein Unterschied dazu, die Pointer direkt zurückzugeben und sie dann in einen Smartpointer zu packen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514278</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514278</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 22 May 2008 12:47:39 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 12:56:27 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Das wuerde mich aber mal interessieren. Wie sollte sowas aussehen? Mehrmals die selbe instanz liefern? Das waere aber mal sehr boese.</p>
</blockquote>
<p>Es kommt darauf an wie die Objekte gestaltet sind und um was es sich für Daten es sich handelt. Bei unveränderlichen Stammdaten kann das durchaus Sinn machen.</p>
<p>Oder ein anderes Beispiel:<br />
Ich habe einen Terminkalender und viele Ansichten auf die gleichen Termine. Eine Änderung in einer der Ansichten muss auch alle anderen betreffen. Warum sollte ich hier verhindern das jede Ansicht mit der gleichen Instanz arbeitet?</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Man kann auch nicht definieren wie der Pointer zerstoert werden soll, denn dann muesste man das interface aendern.</p>
</blockquote>
<p>So? Was kann das folgende den alles bedeuten?</p>
<pre><code class="language-cpp">object* create();
</code></pre>
<p>Es könnte sich um ein klassisches &quot;new object&quot; handeln. Es könnte sich aber auch um einen Speicherbereich handeln der mit malloc etc generiert wurde (und wo vielleicht der replace-new operator verwendet wird). Es könnte sich um einen Wert handeln der je nachdem ob er bereits eingelesen wurde oder nicht aus einem Chache kommt usw. (Alles abhängig vom Anwendungsfall, und alles ohne die Schnittstelle zu ändern).</p>
<pre><code class="language-cpp">Es geht hier rein um ein automatisches delete und das kann der user genauso setzen. oft ist ein scoped_ptr sinnvoller als ein shared_ptr...
</code></pre>
<p>Wenn das zurückgegebene Objekt tatsächlich nur lokal verwendet, und nur eine Instanz davon gehalten wird, ist das Sinnvoll.</p>
<pre><code class="language-cpp">das sind 2 vorteile: welchen nachteil habe ich? der user kann sich gegen die verwendung von smart pointern entscheiden. das ist alles.
</code></pre>
<p>Nachteil:<br />
Bei Zeigern ist nicht garantiert wie sie hergeleitet werden. Ein delete auf einen solchen Zeiger ist nicht unbedingt beabsichtigt. Bei einen shared_ptr weiß ich das die Verwaltung diesem Typ überlassen wird.</p>
<p>Ja es hat ebenso Nachteile, aber ich sehe ebenso Vorteile. Programmierung ist nunmal eine Disziplin der vielen Wege die allesamt korrekt sein können.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514282</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514282</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 22 May 2008 12:56:27 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:04:01 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Man kann auch nicht definieren wie der Pointer zerstoert werden soll, denn dann muesste man das interface aendern.</p>
</blockquote>
<p>Bei einem normalen Zeiger nicht, bei einem shared_ptr kannst du festlegen, wie das gehaltene Objekt zerstört werden soll (falls es überhaupt zerstört werden soll, ein shared_ptr kann theoretisch auch auf statische Daten zeigen). Da hat man ein bisschen mehr Flexibilität.</p>
<p>Wie würdest du das Problem der flexiblen Freigabe lösen? Eine Methode, die das Objekt selbst zerstört (delete this; / free(this); / ...) oder eine freie Funktion (gut, ist jetzt nicht so der große Unterschied)? Oder ganz anders?</p>
<p>Gruß<br />
Don06</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514286</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514286</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Thu, 22 May 2008 13:04:01 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:12:38 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>PS:<br />
der workaround wuerde natuerlich funktionieren, aber es ist einfach unpraktisch x&lt;base&gt; mit x&lt;derived&gt; zu mischen...</p>
</blockquote>
<p>Tut man ja nicht. Man wird nur gezwungen, Smartpointer zu benutzen. Ansonsten ist es kein Unterschied dazu, die Pointer direkt zurückzugeben und sie dann in einen Smartpointer zu packen.</p>
</blockquote>
<p>ich werde gezwungen shared_ptr&lt;derived&gt; zu verwenden auch wenn ich shared_ptr&lt;base&gt; haben will. das ist sehr wohl ein unterschied.</p>
<p>asc schrieb:</p>
<blockquote>
<p>Bei Zeigern ist nicht garantiert wie sie hergeleitet werden. Ein delete auf einen solchen Zeiger ist nicht unbedingt beabsichtigt. Bei einen shared_ptr weiß ich das die Verwaltung diesem Typ überlassen wird.</p>
</blockquote>
<p>ein shared_ptr macht auch nur ein delete.<br />
smart pointer haben keine magie dabei...</p>
<p>es geht darum, dass das delete automatisch gemacht wird, aber warum muss das die factory bestimmen? wenn es der anwender bestimmen kann, hat er viel mehr freiheiten und vorallem kann man dann eben auch die covariant return types verwenden.</p>
<p>ich sehe keinen vorteil darin shared_ptr aus einer factory methode zu liefern. denn das schoene an zeigern ist, dass ich sie jederzeit in einen smart pointer packen kann - und shared_ptr ist der 2. teuerste smart pointer den es gibt. wenn man ihn braucht sind die kosten egal, aber wozu ueberall einsetzen?</p>
<p>in den meisten faellen ist scoped_ptr einfach besser. vorallem ist das ganze hier ein super beispiel warum smart pointer nicht immer die beste wahl sind. man kann natuerlich sagen: ok, dann verzichte ich auch covriant return types - aber ist das nicht eher eine entscheidung die der client code treffen sollte und nicht der provider code?</p>
<p>denn es bringt keine abstraktion oder sonstige vorteile fuer die factory wenn sie direkt einen smart pointer liefert. es ist aber manchmal fuer den client unpraktisch. und smartpointer kann man so oder so verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514296</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514296</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 22 May 2008 13:12:38 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:17:08 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>ein shared_ptr macht auch nur ein delete.<br />
smart pointer haben keine magie dabei...</p>
</blockquote>
<p>Nö, im Konstruktor eines shred_ptr legt man fest, ob z.B. delete, free, oder irgendeine andere Funktion aufgerufen werden soll.</p>
<p><a href="http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/shared_ptr.htm#Members" rel="nofollow">http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/shared_ptr.htm#Members</a></p>
<blockquote>
<p>Custom deallocators allow a factory function returning a shared_ptr to insulate the user from its memory allocation strategy. Since the deallocator is not part of the type, changing the allocation strategy does not break source or binary compatibility, and does not require a client recompilation. For example, a &quot;no-op&quot; deallocator is useful when returning a shared_ptr to a statically allocated object, and other variations allow a shared_ptr to be used as a wrapper for another smart pointer, easing interoperability.</p>
<p>The support for custom deallocators does not impose significant overhead. Other shared_ptr features still require a deallocator to be kept.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1514301</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514301</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Thu, 22 May 2008 13:17:08 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:18:40 GMT]]></title><description><![CDATA[<p>Wäre es trotzdem nicht besser nen rohen Zeiger zurückzugeben und den Clienten entscheiden zu lassen, wo er ihn reinpacken will.<br />
Intern kann man selbst schön mit smart Pointern arbeiten, aber nach außen sollte man einen &quot;reinen&quot; Typen zurückgeben, denn nicht jeder hat boost installiert.</p>
<p>So zwingst du ja den Benutzer deiner Library auch die installation von boost. In einigen Fällen ist das zwar gut, aber bei kleinen Librarys würde ich sowas versuchen zu vermeiden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514304</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514304</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 22 May 2008 13:18:40 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:20:07 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Nein, ist es nicht. Nicht so wie du es anwendest.</p>
</blockquote>
<p>doch, ist es. tachyons einwand war auf die nackten pointer bezogen, nicht auf die shared_ptr.</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>hallo</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>warum nicht einfach einen normalen zeiger zurueck geben?</p>
</blockquote>
<p>weil ein shared_ptr für meine situation sehr gut passen und das interface vereinfachen würde.</p>
</blockquote>
<p>Und ich dachte der Thread geht darueber dass shared_ptr eben nicht passt weil es damit keine covariant return types gibt.</p>
</blockquote>
<p>ähm ja, genau darum geht es. ein shared_ptr würde vom prinzip her für meine situation sehr gut passen und das interface vereinfachen - wenn das problem mit der fehlenden covarianz nicht wäre.</p>
<p>asc schrieb:</p>
<blockquote>
<p>Der Sinn einer solchen Fabrik ist aber das der Typ nicht entscheidend ist (Polymorphie) - sprich eigentlich wäre die Rückgabe von boost::shared_ptr&lt;base&gt; richtig.</p>
</blockquote>
<p>das ist mir bewusst. ich brauche an dieser stelle aber die spezialisierung. base gibt die schnittstelle vor, die nach außen hin relevant ist.<br />
derived implementiert aber plattformspezifische details in form von zusätzlichen funktionen, die sich in base nicht sinnvoll unterbringen lassen. deshalb brauche ich intern ein derived, außerhalb aber nur ein base.</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>in den meisten faellen ist scoped_ptr einfach besser.</p>
</blockquote>
<p>aber der löst auch nicht rein zufällig mein covarianz-problem, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514306</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514306</guid><dc:creator><![CDATA[fabrikarbeiter]]></dc:creator><pubDate>Thu, 22 May 2008 13:20:07 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:22:49 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<p>Wäre es trotzdem nicht besser nen rohen Zeiger zurückzugeben und den Clienten entscheiden zu lassen, wo er ihn reinpacken will.</p>
</blockquote>
<p>Gut, dann wiederhole ich meine Ernst gemeinte Frage:</p>
<p>Don06 schrieb:</p>
<blockquote>
<p>Wie würdest du das Problem der flexiblen Freigabe lösen? Eine Methode, die das Objekt selbst zerstört (delete this; / free(this); / ...) oder eine freie Funktion (gut, ist jetzt nicht so der große Unterschied)? Oder ganz anders?</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1514308</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514308</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Thu, 22 May 2008 13:22:49 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:26:21 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>ein shared_ptr macht auch nur ein delete.<br />
smart pointer haben keine magie dabei...</p>
</blockquote>
<p>Nicht &quot;auch nur ein delete&quot;, sondern eine Zusicherung: Es wird ein delete durchgeführt. Den bei den normalen Zeigern ist es nicht sicher das ein delete beabsichtigt ist!</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>ich sehe keinen vorteil darin shared_ptr aus einer factory methode zu liefern. denn das schoene an zeigern ist, dass ich sie jederzeit in einen smart pointer packen kann - und shared_ptr ist der 2. teuerste smart pointer den es gibt. wenn man ihn braucht sind die kosten egal, aber wozu ueberall einsetzen?</p>
</blockquote>
<p>Um sicherzustellen das die richtige Freigabestrategie gewählt wird, unabhängig davon wie es hinter der Schnittstelle aussieht. Du hast recht das der shared_ptr teuer ist, aber ich Optimiere nicht im voraus, wenn ein Profiler mir sicher sagen kann, das es hier ein Problem in meinen Programm gibt, kann ich immer noch nach alternativen suchen!</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>in den meisten faellen ist scoped_ptr einfach besser.</p>
</blockquote>
<p>Er schließt die Verwendung in Listen etc. aus. Ich ziehe den scoped_ptr für Daten vor, wo ich wirklich garantieren kann das sie Scopebezogen gelten.</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>vorallem ist das ganze hier ein super beispiel warum smart pointer nicht immer die beste wahl sind. man kann natuerlich sagen: ok, dann verzichte ich auch covriant return types - aber ist das nicht eher eine entscheidung die der client code treffen sollte und nicht der provider code?</p>
</blockquote>
<p>Dann würde ich die Factory aber eindeutig steuern (z.B. über Policyklassen), damit GARANTIERT ist was dort zurückgegeben wird.</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>denn es bringt keine abstraktion oder sonstige vorteile fuer die factory wenn sie direkt einen smart pointer liefert. es ist aber manchmal fuer den client unpraktisch. und smartpointer kann man so oder so verwenden.</p>
</blockquote>
<p>Es gibt einen ganz gewaltigen Vorteil den ich aber auch schon erwähnt hatte: Eine Garantie der Freigabestrategie.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514311</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514311</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 22 May 2008 13:26:21 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:44:28 GMT]]></title><description><![CDATA[<p>Don06 schrieb:</p>
<blockquote>
<p>KasF schrieb:</p>
<blockquote>
<p>Wäre es trotzdem nicht besser nen rohen Zeiger zurückzugeben und den Clienten entscheiden zu lassen, wo er ihn reinpacken will.</p>
</blockquote>
<p>Gut, dann wiederhole ich meine Ernst gemeinte Frage:</p>
<p>Don06 schrieb:</p>
<blockquote>
<p>Wie würdest du das Problem der flexiblen Freigabe lösen? Eine Methode, die das Objekt selbst zerstört (delete this; / free(this); / ...) oder eine freie Funktion (gut, ist jetzt nicht so der große Unterschied)? Oder ganz anders?</p>
</blockquote>
</blockquote>
<p>Ich würde es bei meiner Library anders lösen, nämlich einen eigenen smart_ptr bereitstellen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Somit würde ich den User aufzwingen den smart_ptr meiner Lib zu benutzen um so die benutzung von boost zu vermeiden.</p>
<p>Es ist ja ehe nicht das gelbe vom Ei nen rohen Zeiger so zurückzugeben und das weiß vermutlich auch jeder anständige C++ Programmierer, denn niemand weiß woher der Zeiger kommt und wie dafür Speicher alloziert wurde und eigene Funktion der Lib dann bereitzustellen die das Löschen übernehmen, finde ich auch ziemlich eklig.</p>
<p>Also fabrikarbeiter, schreib die deinen eigenen smart_ptr. Das Verhalten zu erziehlen einen smart_ptr&lt;Derivied&gt; in smart_ptr&lt;Base&gt; konvertieren zu lassen ist auch ganz einfach <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514322</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514322</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 22 May 2008 13:44:28 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 13:58:32 GMT]]></title><description><![CDATA[<p>Wer sagt denn, das man boost braucht? shared_ptr gibts im TR1.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514331</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514331</guid><dc:creator><![CDATA[HansiHinterseher]]></dc:creator><pubDate>Thu, 22 May 2008 13:58:32 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 14:06:10 GMT]]></title><description><![CDATA[<p>HansiHinterseher schrieb:</p>
<blockquote>
<p>Wer sagt denn, das man boost braucht? shared_ptr gibts im TR1.</p>
</blockquote>
<p>Stimmt.<br />
Aber leider hat momentan nicht jeder einen Compiler der TR1 bereitstellt und solange müssen die Leute auf boost::tr1 zurückgreifen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514337</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514337</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 22 May 2008 14:06:10 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 16:00:27 GMT]]></title><description><![CDATA[<p>ich bin nicht der meinung, dass der client selber entscheiden können sollte ob er einen schlauen oder einen dummen pointer will. wenn die factory smartpointer zurückliefert, dann sichert man damit ein bestimmtes verhalten zu.</p>
<p>dumme pointer könnten z.b. einfach gelöscht werden, obwohl es an anderen stellen noch x referenzen auf das dahinter liegende objekt gibt. der client weiß einfach nicht, wie lange das objekt gültig bleibt. oder ob, wann und wie er es löschen darf, soll oder <em>muss</em>. wenn ich meine bisherigen erfahrungen so betrachte, ist das eine typische fehlerursache.</p>
<p>mit einem smartpointer ist es klar: der letzte macht das licht aus und der provider entscheidet, wie der lichtschalter aussieht. das ist genau das, was ich meistens will.</p>
<p>dass smartpointer evtl. mehr performance kosten, spielt an dieser stelle eigentlich gar keine rolle. die objekte werden ja nicht in einer tour erzeugt und wieder zerstört.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/4465">@tachyon</a>: wo genau liegt denn die problemlösung bei deinem workaround? ich verstehe nicht, worauf du hinaus willst. dein code hat das gleiche problem hat wie meiner (base_factory::create() und derived_factory::create() mit nicht kovarianten rückgabetypen).</p>
<p>dass die verwendung von boost als nachteil gewertet wird, ist in diesem fall echt lustig. ich habe mich nach jahrelanger weigerung dazu entschieden, boost dieses mal eine chance zu geben, statt das rad immer wieder neu zu erfinden. und schon beim ersten problem kommt der vorschlag, es doch lieber selbst zu programmieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514411</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514411</guid><dc:creator><![CDATA[fabrikarbeiter]]></dc:creator><pubDate>Thu, 22 May 2008 16:00:27 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 18:53:25 GMT]]></title><description><![CDATA[<p>fabrikarbeiter schrieb:</p>
<blockquote>
<p>dass die verwendung von boost als nachteil gewertet wird, ist in diesem fall echt lustig.</p>
</blockquote>
<p>Find ich eher traurig. Boost ist zu einem nicht kleinen Teil von Leuten die im C++ Standardkomitee sitzen beeinflusst wurden. Ich behaupte mal das boost zu den besten C++ Bibliothekssammlungen überhaupt zählt.</p>
<p>Wenn ich mit Strings arbeite verwende ich auch nicht char* sondern std::string, und schreibe keine eigene Umsetzung.</p>
<p>Ich verstehe hier eh nicht warum sich die Leute hier wegen Performance und Overhead aufregen. Wozu gibt es Profiler, wozu gibt es Refactoring, und wo ist bitte die Sicherheit bei dem Ganzen.</p>
<p>Vorzeitige Optimierung ist die Wurzel allen Übels. Warum nicht erst einmal sicheren Code schreiben und dann später die Teile anpassen die tatsächlich ein Flaschenhals in der Anwendung sind. Ich habe inzwischen die Erfahrung in meinen Programmen gemacht, das obwohl ich intensiv mit Smartpointern und ähnlichen Technologien arbeite meine Programme schnell sind. Okay, das liegt natürlich auch an den Anwendungsbereichen. Wenn ich innerhalb kürzester Zeit Abertausende Objekte anlegen muss gibt es besseres - wobei dort dann auch die Frage ist ob nicht replacement new verwendet wird, oder ganz andere Speicherverwaltungsregeln gelten sollten (und spätestens bei Zweiten können nackte Zeiger auch wieder problematisch sein).</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514553</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514553</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 22 May 2008 18:53:25 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Thu, 22 May 2008 20:25:35 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Da bin ich absolut deiner Meinung.Meist liegt ein Performanceeinbruch eh nicht dort, wo man am Anfang erst vermuten würde und es ist schlussendlich viel ineffizienter, wenn du durch vorranige Suche und kopfzerbrechen etwas machst, was schlussendlich eh nicht mehr draufankommt, sondern ein völlig anderer Teil Probleme macht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514649</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514649</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 22 May 2008 20:25:35 GMT</pubDate></item><item><title><![CDATA[Reply to factory + smart pointer on Fri, 23 May 2008 07:06:32 GMT]]></title><description><![CDATA[<p>Wer meint, Smartpointer machen &quot;auch nur ein delete&quot;, dem sei dieser Artikel ans Herz gelegt:<br />
<a href="http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html" rel="nofollow">http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html</a></p>
<p>Mit Shared Pointern kann man theoretisch z.B. full-featured Connectionpooling implementieren. Da ist es aber wenig hilfreich, wenn man dem Aufrufer die Wahl der Verwaltung/Zerstörung überlässt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1514837</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1514837</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Fri, 23 May 2008 07:06:32 GMT</pubDate></item></channel></rss>