<?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[Anlegen von unbekannten Typen]]></title><description><![CDATA[<p>Hallo,</p>
<p>sorry für den blöden Titel, das Problem ist bissi schwer knapp zu beschreiben.<br />
Also, ich hab einen SceneManager, der die Erzeugung/Benutzung/Löschung von Objekten übernimmt. Die Objekte müssen eine Subklasse von ManualObject sein.<br />
Jedes dieser Objekte basiert auf einem Mesh.</p>
<p>Sagen wir ich habe so eine Klasse namens Circle geschrieben:</p>
<pre><code class="language-cpp">class Box : public ManualObject { 
public:
   Box(string name, Mesh* mesh) { ... }
... };
</code></pre>
<p>und jetzt würde ich gerne die Erzeugung/Speicherung und Löschung vom SceneManager übernehmen lassen. Ich hätte also irgendwie gerne sowas (&quot;Pseudocode&quot;):</p>
<pre><code class="language-cpp">// Aufruf: In meinem Beispiel soll createManualObject() ein Box* zurückliefern
ManualObject* box = sceneManager-&gt;createManualObject(&quot;Box&quot;, &quot;meineBox&quot;, &quot;BoxMesh&quot;);

ManualObject* SceneManager::createManualObject(string type, string name, string mesh) {
   Mesh* m = lade Mesh namens mesh
   Erzeuge von ManualObject abgeleitete Klasse, in unserem Fall also ein Box*
   Box* obj = new Box(name, mesh);

   mManualObjectMap[name] = obj; // Scene Manager verwaltet ereugte Objekte
   return obj;
</code></pre>
<p>Der Code geht natürlich nicht. Das Problem ist Zeile 7; ich weiß beim Schreiben des SceneManagers ja nicht, welche Klassen die Anwender mal schreiben werden. Hat wer irgend eine Idee, wie man das implementieren könnte, dass mein SceneManager beliebige von ManualObject abgeleitete Klassen erzeugen (und speichern) kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/249065/anlegen-von-unbekannten-typen</link><generator>RSS for Node</generator><lastBuildDate>Wed, 16 Sep 2026 17:04:29 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/249065.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 02 Sep 2009 11:32:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 11:32:17 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>sorry für den blöden Titel, das Problem ist bissi schwer knapp zu beschreiben.<br />
Also, ich hab einen SceneManager, der die Erzeugung/Benutzung/Löschung von Objekten übernimmt. Die Objekte müssen eine Subklasse von ManualObject sein.<br />
Jedes dieser Objekte basiert auf einem Mesh.</p>
<p>Sagen wir ich habe so eine Klasse namens Circle geschrieben:</p>
<pre><code class="language-cpp">class Box : public ManualObject { 
public:
   Box(string name, Mesh* mesh) { ... }
... };
</code></pre>
<p>und jetzt würde ich gerne die Erzeugung/Speicherung und Löschung vom SceneManager übernehmen lassen. Ich hätte also irgendwie gerne sowas (&quot;Pseudocode&quot;):</p>
<pre><code class="language-cpp">// Aufruf: In meinem Beispiel soll createManualObject() ein Box* zurückliefern
ManualObject* box = sceneManager-&gt;createManualObject(&quot;Box&quot;, &quot;meineBox&quot;, &quot;BoxMesh&quot;);

ManualObject* SceneManager::createManualObject(string type, string name, string mesh) {
   Mesh* m = lade Mesh namens mesh
   Erzeuge von ManualObject abgeleitete Klasse, in unserem Fall also ein Box*
   Box* obj = new Box(name, mesh);

   mManualObjectMap[name] = obj; // Scene Manager verwaltet ereugte Objekte
   return obj;
</code></pre>
<p>Der Code geht natürlich nicht. Das Problem ist Zeile 7; ich weiß beim Schreiben des SceneManagers ja nicht, welche Klassen die Anwender mal schreiben werden. Hat wer irgend eine Idee, wie man das implementieren könnte, dass mein SceneManager beliebige von ManualObject abgeleitete Klassen erzeugen (und speichern) kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770820</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770820</guid><dc:creator><![CDATA[sinna]]></dc:creator><pubDate>Wed, 02 Sep 2009 11:32:17 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:13:33 GMT]]></title><description><![CDATA[<p>Bemüh mal Google mit dem Suchbegriff &quot;Abstract Factory Pattern&quot;.</p>
<p>Edit:</p>
<p>So irgendwie könnte das gehen. Nicht getestet, und mal eben so hingehackt.</p>
<pre><code class="language-cpp">typedef ManualObject* (*CreatorFunction)(std::string const&amp;, std::string const&amp;);

typedef std::map&lt;std::string, CreatorFunction&gt; CreationFunctions;

void SceneManager::registerCreator(std::string const&amp; type, CreatorFunction function)
{
    //m_creatorFunctions ist eine Instanz von CreationFunctions und Member von SceneManager
    CreationFunctions::const_iterator it = m_creatorFunctions.find(type);
    if(it != m_creatorFunctions.end() )
    {
       throw SchonRegistriert;
    }
    m_creatorFunctions[type] = function;
}

ManualObject* SceneManager::createManualObject(std::string const&amp; type, std::string const&amp; name, std::string const&amp; mesh)
{
    CreationFunctions::const_iterator it = m_creatorFunctions.find(type);
    if(it == m_creatorFunctions.end() )
    {
        throw GibtEsNicht;
    }
    ManualObject * obj = (*it)(name, mesh);
    mManualObjectMap[name] = obj;
    return obj;
}

//vom Benutzer definiert

class Box : public ManualObject
{
public:
    Box(std::string const&amp; name, std::string const&amp; mesh);
    //...
    static ManualObject* create(std::string const&amp; name, std::string const&amp; mesh)
    {
        return new Box(name, mesh);
    }
}

//dann später:
sceneManager-&gt;registerCreator(&quot;Box&quot;, Box::create);

//...

ManualObject * obj = sceneManager-&gt;createManualObject(&quot;Box&quot;, &quot;MyBox&quot;, &quot;TheMesh&quot;);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1770827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770827</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:13:33 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:03:28 GMT]]></title><description><![CDATA[<p>Hm, also mir ist nicht klar wie dieses &quot;Abstract Factory Pattern&quot; jetzt bei meinem Problem helfen könnte.<br />
Dieses Pattern bedeutet doch nur: Ich wechsel einfach die Factory aus und die Factory liefert dann die entsprechenden Typen, wobei ich diese nicht kennen muss. z.B. in diesem Beispiel:<br />
<a href="http://sourcemaking.com/design_patterns/abstract_factory/cpp/1" rel="nofollow">http://sourcemaking.com/design_patterns/abstract_factory/cpp/1</a></p>
<pre><code class="language-cpp">int main() {
#ifdef MOTIF
   factory = new MotifFactory;
#else // WINDOWS
   factory = new WindowsFactory;
#endif
   Widget* w = factory-&gt;create_button();
   w-&gt;draw();
   display_window_one();
   display_window_two();
}
</code></pre>
<p>Eine MotifFactory liefert bei create_button() zb einen MotifButton* usw.</p>
<p>Mein SceneManager ist so eine Art Factory, aber ich will definitiv NICHT mehrere SceneManager haben. Außerdem waren in allen Beispielen, die ich zu dem Factory Pattern gefunden habe, die Typen bereits bekannt. Sprich ein MotifFactory::create_button() liefert immer einen MotifButton* usw. Bei mir sind die Subklassen von ManualObject zum Zeitpunkt wenn ich die Methode createManualObject() schreibe ja NICHT bekannt.<br />
Wären da vielleicht Templates eine Möglichkeit?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770842</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770842</guid><dc:creator><![CDATA[sinna]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:03:28 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:04:51 GMT]]></title><description><![CDATA[<p>Schau Dir mal meinen editierten Beitrag an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770845</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770845</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:04:51 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:07:35 GMT]]></title><description><![CDATA[<p>Die Erzeugung ist eine Sache, die Speicherung eine andere. Für zwei verschiedene Aufgaben solltest du auch zwei verschiedene Klassen haben.<br />
Für die Erzeugung brauchst du eine Factory, und der Benutzer, der neue Klassen schreibt, muss auch die Factory entsprechend anpassen. Für die Speicherung kannst du selber eine Klasse schreiben, da du dafür ja nicht mehr wissen musst was für ein Objekt sich hinter dem ManualObject* wirklich verbirgt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770850</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770850</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:07:35 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:15:17 GMT]]></title><description><![CDATA[<p>Vielen Dank für deinen Code Tachyon. Das gefällt mir schon ziemlich gut. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Wenn ich dann noch</p>
<pre><code class="language-cpp">static ManualObject* createBox(std::string const&amp; name, std::string const&amp; mesh) {
return new Box(name, mesh);
 }
</code></pre>
<p>pure virtual mache und nach ManualObject verschiebe, dann müssen die konkreten Subklassen so eine &quot;Erzeugerfunktion&quot; implementieren.</p>
<p>Ist dein Code eigentlich noch das Pattern &quot;Abstract Factory Pattern&quot;?</p>
<p>Ich denke ich werde deine Lösung nehmen, aber nur zur Vollständigkeit: Ginge auch eine Lösung mit Templates? Also irgendwie sowas:</p>
<pre><code class="language-cpp">template&lt;class SubClassOfManualObject&gt;
SubClassOfManualObject* SceneManager::createManualObject(std::string const&amp; name, std::string const&amp; mesh) {

   SubClassOfManualObject* obj = new SubClassOfManualObject(name, mesh);
   mManualObjectMap[name] = obj; // Scene Manager verwaltet ereugte Objekte
   return obj;
}
</code></pre>
<p>?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770855</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770855</guid><dc:creator><![CDATA[sinna]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:15:17 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:22:40 GMT]]></title><description><![CDATA[<p>sinna schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Es ist doch später egal, ob es <code>Box</code> , <code>Circle</code> oder sonstwas ist.<br />
Der Zugriff erfolgt über <code>ManualObject</code> . Deshalb brauchst Du kein Template. Außerdem wäre es schlecht, wenn die erzeugende Funktion virtuell wäre. Dann brächtest Du nämlich ein erst Objekt das von <code>ManualObject</code> abgeleitet wurde, um die Objekte zu erzeugen.<br />
Und ja, das ist eine Variante vom Factory Pattern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770860</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770860</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:22:40 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:25:02 GMT]]></title><description><![CDATA[<p>sinna schrieb:</p>
<blockquote>
<p>Vielen Dank für deinen Code Tachyon. Das gefällt mir schon ziemlich gut. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Wenn ich dann noch</p>
<pre><code class="language-cpp">static ManualObject* createBox(std::string const&amp; name, std::string const&amp; mesh) {
return new Box(name, mesh);
 }
</code></pre>
<p>pure virtual mache und nach ManualObject verschiebe, dann müssen die konkreten Subklassen so eine &quot;Erzeugerfunktion&quot; implementieren.</p>
</blockquote>
<p>Dann müsstest du um ein Objekt zu erzeugen aber im Programmcode createBox als Methode von einem anderen ManualObject aufrufen - was hieße, dass ein Objekt das nächste erzeugt. Das ist vermutlich nicht wirklich sinnvoll (zumal dann noch das Problem besteht, wie man das erse Objekt erzeugt).</p>
<blockquote>
<p>Ich denke ich werde deine Lösung nehmen, aber nur zur Vollständigkeit: Ginge auch eine Lösung mit Templates? Also irgendwie sowas:</p>
<pre><code class="language-cpp">template&lt;class SubClassOfManualObject&gt;
SubClassOfManualObject* SceneManager::createManualObject(std::string const&amp; name, std::string const&amp; mesh) {

   SubClassOfManualObject* obj = new SubClassOfManualObject(name, mesh);
   mManualObjectMap[name] = obj; // Scene Manager verwaltet ereugte Objekte
   return obj;
}
</code></pre>
<p>?</p>
</blockquote>
<p>Dafür müsstest du im Code bereits wissen von welchem Typ das zu erzeugende Objekt ist, um den richtigen Templateparameter mitgeben zu können. Das macht die ganze Factory-Methode sinnfrei, weil du dann genausogut direkt den Ctor aufrufen könntest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1770863</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770863</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:25:02 GMT</pubDate></item><item><title><![CDATA[Reply to Anlegen von unbekannten Typen on Wed, 02 Sep 2009 12:29:03 GMT]]></title><description><![CDATA[<p>Argh, stimmt ja, daran hab ich garnicht gedacht.</p>
<p>Vielen Dank für die schnelle Hilfe euch beiden! <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/1770871</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1770871</guid><dc:creator><![CDATA[sinna]]></dc:creator><pubDate>Wed, 02 Sep 2009 12:29:03 GMT</pubDate></item></channel></rss>