<?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[Eine Art Factory]]></title><description><![CDATA[<p>Hallo!</p>
<p>Es liegen folgende Klasse vor:</p>
<pre><code class="language-cpp">class FooBase
{};

class Foo1 : public FooBase
{};

class Foo2 : public FooBase
{};
</code></pre>
<p>Nun soll mit den Klassen innerhalb einer Methode (einer anderen Klasse) gearbeitet werden. Je nach Auswahl aber mit Foo1 oder Foo2.</p>
<pre><code class="language-cpp">class MyClass
{
public:
    void DoSomething(FooBase &amp; fb);
};
</code></pre>
<p>Aufgerufen wird DoSomething bisher so:</p>
<pre><code class="language-cpp">void AnotherClass::Method(const int &amp; Id)
{
    if (Id == 0)
        this-&gt;m_MyClass.DoSomething(Foo1());
    else
        this-&gt;m_MyClass.DoSomething(Foo2());
}
</code></pre>
<p>Diese if-Abfrage stört mich, denn sie ist zu umständlich, da später später noch mehr von FooBase abgeleitete Klassen hinzukommen werden. Ich dachte an so etwas wie eine Factory mit einem auto_ptr als Member, da in MyClass::DoSomething Ausnahmen geworfen werden.</p>
<p>Meine erdachte Lösung. Eine neue Factory Klasse, die die if-Abfragen kapselt.</p>
<pre><code class="language-cpp">class FooFactory
{
private:
    std::auto_ptr&lt;FooBase *&gt; m_pFooBase;
public:
    FooBase &amp; Create(const int &amp; Id)
    { 
        if (Id == 0)
            this-&gt;m_pFooBase = new Foo1;
        else
            this-&gt;m_pFooBase = new Fo21;

        return *m_pFooBase
    }
};
</code></pre>
<p>Ist das so möglich und wird m_pFooBase auch wirklich bei Ausnahmen gelöscht? Gibt es vielleicht eine andere, wesentlich bessere Herangehensweise?</p>
<p>Gruß Klaas</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/245302/eine-art-factory</link><generator>RSS for Node</generator><lastBuildDate>Fri, 18 Sep 2026 19:29:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/245302.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 12 Jul 2009 15:01:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Eine Art Factory on Sun, 12 Jul 2009 15:01:58 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Es liegen folgende Klasse vor:</p>
<pre><code class="language-cpp">class FooBase
{};

class Foo1 : public FooBase
{};

class Foo2 : public FooBase
{};
</code></pre>
<p>Nun soll mit den Klassen innerhalb einer Methode (einer anderen Klasse) gearbeitet werden. Je nach Auswahl aber mit Foo1 oder Foo2.</p>
<pre><code class="language-cpp">class MyClass
{
public:
    void DoSomething(FooBase &amp; fb);
};
</code></pre>
<p>Aufgerufen wird DoSomething bisher so:</p>
<pre><code class="language-cpp">void AnotherClass::Method(const int &amp; Id)
{
    if (Id == 0)
        this-&gt;m_MyClass.DoSomething(Foo1());
    else
        this-&gt;m_MyClass.DoSomething(Foo2());
}
</code></pre>
<p>Diese if-Abfrage stört mich, denn sie ist zu umständlich, da später später noch mehr von FooBase abgeleitete Klassen hinzukommen werden. Ich dachte an so etwas wie eine Factory mit einem auto_ptr als Member, da in MyClass::DoSomething Ausnahmen geworfen werden.</p>
<p>Meine erdachte Lösung. Eine neue Factory Klasse, die die if-Abfragen kapselt.</p>
<pre><code class="language-cpp">class FooFactory
{
private:
    std::auto_ptr&lt;FooBase *&gt; m_pFooBase;
public:
    FooBase &amp; Create(const int &amp; Id)
    { 
        if (Id == 0)
            this-&gt;m_pFooBase = new Foo1;
        else
            this-&gt;m_pFooBase = new Fo21;

        return *m_pFooBase
    }
};
</code></pre>
<p>Ist das so möglich und wird m_pFooBase auch wirklich bei Ausnahmen gelöscht? Gibt es vielleicht eine andere, wesentlich bessere Herangehensweise?</p>
<p>Gruß Klaas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1741522</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1741522</guid><dc:creator><![CDATA[Klaas123]]></dc:creator><pubDate>Sun, 12 Jul 2009 15:01:58 GMT</pubDate></item><item><title><![CDATA[Reply to Eine Art Factory on Sun, 12 Jul 2009 16:06:48 GMT]]></title><description><![CDATA[<p>Würde sich <code>switch</code> nicht eignen, oder sehe ich da etwas falsch? Musst du für die Erstellung der <code>FooBase</code> -Derivate eine eigene Klasse haben, reicht eine Funktion nicht?</p>
<p>Und ja, wenn du <code>std::auto_ptr</code> verwendest, wird der Speicher beim Verlassen des Scopes auf jeden Fall freigegeben, also auch bei Exceptions (vorausgesetzt, dein Smart Pointer besitzt das Objekt).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1741553</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1741553</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 12 Jul 2009 16:06:48 GMT</pubDate></item><item><title><![CDATA[Reply to Eine Art Factory on Sun, 12 Jul 2009 16:11:00 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Würde sich <code>switch</code> nicht eignen, oder sehe ich da etwas falsch? Musst du für die Erstellung der <code>FooBase</code> -Derivate eine eigene Klasse haben, reicht eine Funktion nicht?</p>
</blockquote>
<p>switch nimmt sogar mehr Platz ein als die if-Abfragen. Ich möchte meine Funktion nicht so unnötig aufblähen, daher wollte ich den Code in eine Factory auslagern.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Und ja, wenn du <code>std::auto_ptr</code> verwendest, wird der Speicher beim Verlassen des Scopes auf jeden Fall freigegeben, also auch bei Exceptions (vorausgesetzt, dein Smart Pointer besitzt das Objekt).</p>
</blockquote>
<p>Was eminst Du mit &quot;dein Smart Pointer besitzt das Objekt&quot;? Er wird in <code>FooFactory::Create</code> nur dereferenziert und als Referenz zurückgegeben um in anderen eine Referenz anstatt eines Zeigers zu nutzen. Diese Referenz wird ganz &quot;normal&quot; genutzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1741556</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1741556</guid><dc:creator><![CDATA[Klaas123]]></dc:creator><pubDate>Sun, 12 Jul 2009 16:11:00 GMT</pubDate></item><item><title><![CDATA[Reply to Eine Art Factory on Sun, 12 Jul 2009 16:21:53 GMT]]></title><description><![CDATA[<p>Klaas123 schrieb:</p>
<blockquote>
<p>switch nimmt sogar mehr Platz ein als die if-Abfragen. Ich möchte meine Funktion nicht so unnötig aufblähen, daher wollte ich den Code in eine Factory auslagern.</p>
</blockquote>
<p>Gut, aber bei vielen Fällen kann sich <code>switch</code> schnell einmal auszahlen. Platz braucht es auch nicht mehr als <code>if</code> , sogar eher weniger.</p>
<pre><code class="language-cpp">switch (ID)
{
    case 1:   return new Foo1();   break;
    case 2:   return new Foo2();   break;
    case 3:   return new Foo3();   break;
    default:  return new FooD();
}
</code></pre>
<p>Klaas123 schrieb:</p>
<blockquote>
<p>Was eminst Du mit &quot;dein Smart Pointer besitzt das Objekt&quot;? Er wird in <code>FooFactory::Create</code> nur dereferenziert und als Referenz zurückgegeben um in anderen eine Referenz anstatt eines Zeigers zu nutzen. Diese Referenz wird ganz &quot;normal&quot; genutzt.</p>
</blockquote>
<p>Meine Aussage ist eigentlich nicht so weltbewegend. Ich meinte nur Folgendes:</p>
<pre><code class="language-cpp">std::auto_ptr&lt;foo&gt; function()
{
    std::auto_ptr&lt;foo&gt; foo_ptr(new foo());

    if (...)
        throw std::runtime_error(&quot;bla&quot;); // zerstört das Objekt beim Verlassen des Scopes.
    else
        return foo_ptr; // hier wird das Objekt natürlich nicht zerstört.
}
</code></pre>
<p>Also wenn der Smart-Pointer das Objekt nicht mehr besitzt (d.h. er zeigt auf Null, da er den Besitz weitergegeben hat), gibt er dieses logischerweise auch nicht frei. Tut mir leid, wenn ich deswegen Verwirrung gestiftet habe. <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/1741564</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1741564</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 12 Jul 2009 16:21:53 GMT</pubDate></item><item><title><![CDATA[Reply to Eine Art Factory on Mon, 13 Jul 2009 06:28:42 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Gut, aber bei vielen Fällen kann sich <code>switch</code> schnell einmal auszahlen. Platz braucht es auch nicht mehr als <code>if</code> , sogar eher weniger.</p>
</blockquote>
<p><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="🙂"
    /> So stimmt, das zwar, jedoch würde das gegen &quot;meine&quot; Codierrichtlinien verstoßen, da das return statement nicht in der gleichen Zeile stehen darf. Zudem ist das break doch sogar überflüssig, oder?</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Also wenn der Smart-Pointer das Objekt nicht mehr besitzt (d.h. er zeigt auf Null, da er den Besitz weitergegeben hat), gibt er dieses logischerweise auch nicht frei. Tut mir leid, wenn ich deswegen Verwirrung gestiftet habe. <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>
</blockquote>
<p>Jetzt bin ich erst recht verwirrt. <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="😉"
    /><br />
Also, in der <code>FooFactory</code> -Klasse ist doch der std::auto_ptr ein Member und ich gebe hier eine Referenz auf das Objekt zurück. Somit wird doch nichts hin und her kopiert und das Objekt bei einer Exception gelöscht. Dachte ich zumindest...</p>
<p>Gruß<br />
Klaas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1741866</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1741866</guid><dc:creator><![CDATA[Klaas123]]></dc:creator><pubDate>Mon, 13 Jul 2009 06:28:42 GMT</pubDate></item><item><title><![CDATA[Reply to Eine Art Factory on Mon, 13 Jul 2009 09:03:29 GMT]]></title><description><![CDATA[<p>Klaas123 schrieb:</p>
<blockquote>
<p><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="🙂"
    /> So stimmt, das zwar, jedoch würde das gegen &quot;meine&quot; Codierrichtlinien verstoßen, da das return statement nicht in der gleichen Zeile stehen darf.</p>
</blockquote>
<p>Okay. Es wäre halt auch schneller als mehrere <code>if</code> -Abfragen. Und wenn du schon eine eigene Klasse für die Erzeugung hast, dürfte ein bisschen mehr Code eigentlich nicht dramatisch sein (obwohl es eigentlich nicht wirklich mehr ist, auch wenn du die <code>case</code> s und <code>return</code> s auf verschiedene Zeilen schreibst). <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>
<p>Klaas123 schrieb:</p>
<blockquote>
<p>Zudem ist das break doch sogar überflüssig, oder?</p>
</blockquote>
<p>Argh, natürlich. Ich hatte es zuerst auch nicht drin, beim Überfliegen des Codes hab ich dann gedacht: &quot;oh, ein switch ohne break&quot; und ohne viel zu überlegen <code>break</code> hingeschrieben. <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>
<p>Klaas123 schrieb:</p>
<blockquote>
<p>Jetzt bin ich erst recht verwirrt. <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="😉"
    /><br />
Also, in der <code>FooFactory</code> -Klasse ist doch der std::auto_ptr ein Member und ich gebe hier eine Referenz auf das Objekt zurück. Somit wird doch nichts hin und her kopiert und das Objekt bei einer Exception gelöscht. Dachte ich zumindest...</p>
</blockquote>
<p>Das stimmt schon. Ich meinte eigentlich nur, dass der Smart-Pointer nicht mehr für die Freigabe verantwortlich ist, sobald er seinen Besitz an einen anderen <code>std::auto_ptr</code> weitergegeben hat. Das heisst nicht, dass du ein Memory Leak hast (das sicher nicht, der Speicher wird sicher freigegeben), aber die Freigabe erfolgt eben nicht unter allen Umständen beim Verlassen des Scopes.</p>
<p>Dafür ist mir noch was anderes aufgefallen:</p>
<pre><code class="language-cpp">std::auto_ptr&lt;FooBase *&gt; m_pFooBase;
</code></pre>
<p>müsste wohl so heissen:</p>
<pre><code class="language-cpp">std::auto_ptr&lt;FooBase&gt; m_pFooBase;
</code></pre>
<p>Ausserdem ist der <code>std::auto_ptr&lt;T&gt;::operator=</code> nicht für Zeiger überladen, statt</p>
<pre><code class="language-cpp">this-&gt;m_pFooBase = new Foo1;
</code></pre>
<p>sollte dort</p>
<pre><code class="language-cpp">this-&gt;m_pFooBase.reset(new Foo1);
</code></pre>
<p>stehen (auch wenn ichs ohne <code>this-&gt;</code> machen würde).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1741942</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1741942</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 13 Jul 2009 09:03:29 GMT</pubDate></item><item><title><![CDATA[Reply to Eine Art Factory on Mon, 13 Jul 2009 13:52:48 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Dafür ist mir noch was anderes aufgefallen:</p>
</blockquote>
<p>Danke für die Hinweise, wird mir sicherlich ein paar Compiler-Fehler sparen, jedoch sollte es nur Demo-Code sein (wobei auch dieser sytaktisch korrekt sein sollte <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/1742141</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1742141</guid><dc:creator><![CDATA[Klaas123]]></dc:creator><pubDate>Mon, 13 Jul 2009 13:52:48 GMT</pubDate></item></channel></rss>