<?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[Templates für Fortgeschrittene]]></title><description><![CDATA[<p>Hi,<br />
ich habe eine Klasse Base:</p>
<pre><code class="language-cpp">class Base
{
public:
  virtual Base *createDerived()
  {
    return 0;
  }
};
</code></pre>
<p>und eine davon abgeleitete Template Klasse BaseT:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
class BaseT : public Base
{
public:
  virtual Base *createDerived()
  {
    return new DerivedT&lt;T&gt;();  //nicht schön, da Wissen von Ableitung benötigt
  }
};
</code></pre>
<p>und eine weitere davon abgeleitete Template Klasse DerivedT:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
class DerivedT : public BaseT&lt;T&gt;
{

};
</code></pre>
<p>So weit so gut. Angenommen ich habe eine Objekt:</p>
<pre><code class="language-cpp">Base *base = new BaseT&lt;int&gt;;
</code></pre>
<p>Dann möchte ich etwas haben wie:</p>
<pre><code class="language-cpp">Base *derived = base-&gt;createDerived();
</code></pre>
<p>Das heißt, ein Objekt vom Typ DerivedT, dass den selben Template-Typen hat wie mein &quot;base&quot; Objekt.</p>
<p>Mein Ansatz funktioniert zwar, ist aber nicht besonders schön (siehe Kommentar).</p>
<p>Mein bevorzugter Ansatz wäre eine Fabrik:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
class Factory
{
public:
  static Base *createDerived()
  {
    return new DerivedT&lt;T&gt;();
  }
};
</code></pre>
<p>Und jetzt fangen die Probleme an:<br />
Wie sage ich der Factory, welchen Typ sie verwenden soll. Es soll ja derselbe typ sein wie der von &quot;base&quot;.</p>
<pre><code class="language-cpp">Base *derived2 = Factory&lt;sameAsBase&gt;::createDerived();
</code></pre>
<p>Und da stößt C++ an seine Grenzen. Kennt jemand einen Ausweg?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/261676/templates-für-fortgeschrittene</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 03:47:02 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/261676.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 22 Feb 2010 13:00:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 13:00:49 GMT]]></title><description><![CDATA[<p>Hi,<br />
ich habe eine Klasse Base:</p>
<pre><code class="language-cpp">class Base
{
public:
  virtual Base *createDerived()
  {
    return 0;
  }
};
</code></pre>
<p>und eine davon abgeleitete Template Klasse BaseT:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
class BaseT : public Base
{
public:
  virtual Base *createDerived()
  {
    return new DerivedT&lt;T&gt;();  //nicht schön, da Wissen von Ableitung benötigt
  }
};
</code></pre>
<p>und eine weitere davon abgeleitete Template Klasse DerivedT:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
class DerivedT : public BaseT&lt;T&gt;
{

};
</code></pre>
<p>So weit so gut. Angenommen ich habe eine Objekt:</p>
<pre><code class="language-cpp">Base *base = new BaseT&lt;int&gt;;
</code></pre>
<p>Dann möchte ich etwas haben wie:</p>
<pre><code class="language-cpp">Base *derived = base-&gt;createDerived();
</code></pre>
<p>Das heißt, ein Objekt vom Typ DerivedT, dass den selben Template-Typen hat wie mein &quot;base&quot; Objekt.</p>
<p>Mein Ansatz funktioniert zwar, ist aber nicht besonders schön (siehe Kommentar).</p>
<p>Mein bevorzugter Ansatz wäre eine Fabrik:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
class Factory
{
public:
  static Base *createDerived()
  {
    return new DerivedT&lt;T&gt;();
  }
};
</code></pre>
<p>Und jetzt fangen die Probleme an:<br />
Wie sage ich der Factory, welchen Typ sie verwenden soll. Es soll ja derselbe typ sein wie der von &quot;base&quot;.</p>
<pre><code class="language-cpp">Base *derived2 = Factory&lt;sameAsBase&gt;::createDerived();
</code></pre>
<p>Und da stößt C++ an seine Grenzen. Kennt jemand einen Ausweg?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859492</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859492</guid><dc:creator><![CDATA[diavo]]></dc:creator><pubDate>Mon, 22 Feb 2010 13:00:49 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 13:29:54 GMT]]></title><description><![CDATA[<p>Edit: //War quatsch</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859506</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859506</guid><dc:creator><![CDATA[evilissimo]]></dc:creator><pubDate>Mon, 22 Feb 2010 13:29:54 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 13:37:25 GMT]]></title><description><![CDATA[<p>Warum machst du aus der Factory-Klasse nicht eine Factory-Methode?</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
Base* createDreived()
{
    return new DerivedT&lt;T&gt;();
}

//--&gt;&gt;
Base* b = createDerived&lt;int&gt;();
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1859524</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859524</guid><dc:creator><![CDATA[sabberschnecke]]></dc:creator><pubDate>Mon, 22 Feb 2010 13:37:25 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 14:00:30 GMT]]></title><description><![CDATA[<p>Und was hilft mir das? Das Problem bleibt doch das gleiche, oder?</p>
<pre><code>Base* b = createDerived&lt;int&gt;();
</code></pre>
<p>Das Oroblem ist, ich weiß nicht welchen Typ ich übergeben muss.<br />
Der Typ soll ja der gleiche sein wie aus &quot;base&quot;:</p>
<pre><code>Base *base = new BaseT&lt;int&gt;;
</code></pre>
<p>Angenommen ich habe eine Funktion, die nicht weiß wie base erstellt wurde:</p>
<pre><code>void test(Base *base)
{
Base* derived = createDerived&lt;type von base&gt;();	
}
</code></pre>
<p>Hm... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859552</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859552</guid><dc:creator><![CDATA[diavo]]></dc:creator><pubDate>Mon, 22 Feb 2010 14:00:30 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 14:09:13 GMT]]></title><description><![CDATA[<p>Dann muss deine Klasse selber auch ne Factory sein. Denn den Typen extrahieren, um ihn als template-Parameter zu übergeben, funktioniert nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859558</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859558</guid><dc:creator><![CDATA[sabberschnecke]]></dc:creator><pubDate>Mon, 22 Feb 2010 14:09:13 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 14:27:45 GMT]]></title><description><![CDATA[<p>Spendier Deinen Klassen eine clone() Methode, die jeweils eine neue Instanz der Klasse zurückliefert. Sowas wie:</p>
<pre><code>class Base
{
   ...
   Base * clone() = 0;
}

class DerivedA : public Base
{
   Base * clone() {return new DerivedA;}
}

class DerivedB : public Base
{
   Base * clone() {return new DerivedB;}
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1859578</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859578</guid><dc:creator><![CDATA[jencas]]></dc:creator><pubDate>Mon, 22 Feb 2010 14:27:45 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 15:14:17 GMT]]></title><description><![CDATA[<p>Im prinzin ne gute Idee aber:</p>
<pre><code class="language-cpp">class DerivedA : public Base
{
   Base * clone() {return new DerivedA;}
}
</code></pre>
<p>Die clone von DerivedA soll ja eine Instanz von DerivedB erstellen. Und somit bin ich wieder am Anfang, denn DerivedA soll DerivedB möglichst nicht kennen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859603</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859603</guid><dc:creator><![CDATA[diavo]]></dc:creator><pubDate>Mon, 22 Feb 2010 15:14:17 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 15:18:07 GMT]]></title><description><![CDATA[<p>diavo schrieb:</p>
<blockquote>
<p>Die clone von DerivedA soll ja eine Instanz von DerivedB erstellen. Und somit bin ich wieder am Anfang, denn DerivedA soll DerivedB möglichst nicht kennen.</p>
</blockquote>
<p>Es wird immer spannender! Wieso soll jetzt DerivedA eine Instanz von DerivedB erstellen? Und was hat das mit den Templates zu tun? Und, klar, wenn eine Methode etwas mit einem Type anstellen muss, dann muss natürlich der Type bekannt sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859605</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859605</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Mon, 22 Feb 2010 15:18:07 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Mon, 22 Feb 2010 15:30:27 GMT]]></title><description><![CDATA[<p>Ok, hier ein Beispiel das zeigt dass es geht.</p>
<pre><code class="language-cpp">struct Base
{
    virtual Base* create()=0;
};

template &lt;typename T&gt;
struct DerivedB;

template &lt;typename T&gt;
struct DerivedA : public Base
{
    T val;
    DerivedA* create() {
        return new DerivedA;
    }
    DerivedB&lt;T&gt;* createB();
};

template &lt;typename T&gt;
struct DerivedB : public Base
{
    T val;
    DerivedB* create() {
        return new DerivedB;
    }
};

template &lt;typename T&gt;
DerivedB&lt;T&gt;*
DerivedA&lt;T&gt;::createB() {
    return new DerivedB&lt;T&gt;;
}

int main()
{
    DerivedA&lt;int&gt; da1;
    Base* b1 = da1.createB();
    Base* b2 = b1-&gt;create();

    DerivedB&lt;int&gt;* db1 = dynamic_cast&lt;DerivedB&lt;int&gt;*&gt;(b2);
    DerivedB&lt;int&gt;* d2 = db1-&gt;create();
}
</code></pre>
<p>Und bitte sag konkret, was dir nicht passt und vor allem die endgültige Vorgabe, was dein Konstrukt können muss. Sonst geht das hier noch ewig <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/1859608</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859608</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Mon, 22 Feb 2010 15:30:27 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Tue, 23 Feb 2010 07:54:39 GMT]]></title><description><![CDATA[<p>Hi,<br />
also das letzte Beispiel</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
struct DerivedA : public Base
{
    T val;
    DerivedA* create() {
        return new DerivedA;
    }
    DerivedB&lt;T&gt;* createB();
};
</code></pre>
<p>ist kein gutes Design, weil ja DerivedA die abgeleitete Klasse DerivedB kennen muss. Das war ja auch mein 1. Vorschlag.<br />
Ich möchte also eine Möglichkeit genau das zu tun, was dieses Beispiel tut, aber eben ohne die zirkuläre Abhängkeit von DerivedA und DerivedB.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859891</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859891</guid><dc:creator><![CDATA[diavo]]></dc:creator><pubDate>Tue, 23 Feb 2010 07:54:39 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Tue, 23 Feb 2010 08:12:57 GMT]]></title><description><![CDATA[<p>in dem Beispiel ist nichts zirkulär.</p>
<p>natürlich wird das mit einer Factory nicht gehen, da du dafür den Typ brauchst, wie du bereits erkannt hast. Da dein Abstraktionsmodell ganz klar sagt: &quot;Ich werfe den Typen weg&quot; wirst du um eine Factorymethode nicht herumkommen.</p>
<p>Einzige gangbare Alternative: die Entität, die dir dein BaseT erzeugt, muss dann auch dein Derived erzeugen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859898</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859898</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Tue, 23 Feb 2010 08:12:57 GMT</pubDate></item><item><title><![CDATA[Reply to Templates für Fortgeschrittene on Tue, 23 Feb 2010 08:40:32 GMT]]></title><description><![CDATA[<p>Ok. Das hatte ich schon vermutet. Danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1859907</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1859907</guid><dc:creator><![CDATA[diavo]]></dc:creator><pubDate>Tue, 23 Feb 2010 08:40:32 GMT</pubDate></item></channel></rss>