<?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[Erstellung von Objekten und Zuweisung: Chic oder nicht?]]></title><description><![CDATA[<p>Hi,</p>
<p>ich habe Mal wieder eine mögliche Designfrage, sprich: Ich erzähle euch, was ich hier habe und erhoffe mir Vorschläge oder Zustimmungen, ob das so gut designed scheint. Wieso? Weil ich mich laufend verbessern möchte, selbst wenn ich mein Design gerade ganz gut finde.</p>
<p>So, nach dem ersten Absatz sind hier sicher nur noch Leute, die an meinem &quot;Problem&quot; interessiert sind. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
<p>Also, ich habe meine berühmt-berüchtigte Model-Klasse, die ein geladenes 3D-Modell repräsentiert. Ein solches Modell kann einen Kollisionskörper haben (d.h. z.B. ein Baum von Sphären, die das Modell annähern), muss aber nicht! Und das soll sich der Benutzer nach dem Laden selbst aussuchen können und den Körper quasi über DI reinschmuggeln. Der Sphärenbaum wird aber nicht nur durch den ctor erstellt, sondern extern durch eine freie Funktion, da der Prozess recht aufwendig ist und insbesondere viele Hilfsstrukturen und Hilfsfunktionen genutzt werden.</p>
<p>Konkret muss der Benutzer jetzt Folgendes machen:</p>
<pre><code class="language-cpp">unique_ptr&lt;Model&gt; ehRock;
ehRock.reset(loadModel(&quot;D:/3D-Modelle/Statisch/Rock/rock_1.dae&quot;));
ehRock-&gt;SetCollisionBody(createBoundingSphereTree(ehRock, 3));
</code></pre>
<p>(Bitte keine Belehrungen zu absoluten Pfaden, das ist ein reines Testprojekt, da nutze ich mein privates Modell-Reposistory, das abseits des eigentlichen Projekts liegt)</p>
<p>Auch das Modell wird über eine FactoryMethod geladen, da unterschiedliche Loader dahinterstecken können und das Erstellen ebenfalls ziemlich aufwendig ist.</p>
<p>Was mich jetzt etwas stört: loadModel und createBoundingSphereTree liefern jeweils ein mit new erzeugtes Objekt zurück. Man kann das Ergebnis in einen Smartptr verfrachten und ist zufrieden. Aber wie mache ich das meinem Benutzer klar, der meine Engine nutzt? Wenn der aufmerksam ist, wird er sich ja fragen, ob er den Speicher freigeben muss ohne zu wissen, dass Model das bereits erledigt (was ich bisher z.B. auch euch gegenüber nicht erwähnt habe).</p>
<p>Also wie löse ich die Problematik, dass sehr große mit new erzeugte Objekte über Funktionen zurückgegeben werden und der Nutzer das u.U. gar nicht weiß?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/289718/erstellung-von-objekten-und-zuweisung-chic-oder-nicht</link><generator>RSS for Node</generator><lastBuildDate>Tue, 18 Aug 2026 23:51:52 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/289718.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 11 Jul 2011 14:44:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Erstellung von Objekten und Zuweisung: Chic oder nicht? on Mon, 11 Jul 2011 14:44:40 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich habe Mal wieder eine mögliche Designfrage, sprich: Ich erzähle euch, was ich hier habe und erhoffe mir Vorschläge oder Zustimmungen, ob das so gut designed scheint. Wieso? Weil ich mich laufend verbessern möchte, selbst wenn ich mein Design gerade ganz gut finde.</p>
<p>So, nach dem ersten Absatz sind hier sicher nur noch Leute, die an meinem &quot;Problem&quot; interessiert sind. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
<p>Also, ich habe meine berühmt-berüchtigte Model-Klasse, die ein geladenes 3D-Modell repräsentiert. Ein solches Modell kann einen Kollisionskörper haben (d.h. z.B. ein Baum von Sphären, die das Modell annähern), muss aber nicht! Und das soll sich der Benutzer nach dem Laden selbst aussuchen können und den Körper quasi über DI reinschmuggeln. Der Sphärenbaum wird aber nicht nur durch den ctor erstellt, sondern extern durch eine freie Funktion, da der Prozess recht aufwendig ist und insbesondere viele Hilfsstrukturen und Hilfsfunktionen genutzt werden.</p>
<p>Konkret muss der Benutzer jetzt Folgendes machen:</p>
<pre><code class="language-cpp">unique_ptr&lt;Model&gt; ehRock;
ehRock.reset(loadModel(&quot;D:/3D-Modelle/Statisch/Rock/rock_1.dae&quot;));
ehRock-&gt;SetCollisionBody(createBoundingSphereTree(ehRock, 3));
</code></pre>
<p>(Bitte keine Belehrungen zu absoluten Pfaden, das ist ein reines Testprojekt, da nutze ich mein privates Modell-Reposistory, das abseits des eigentlichen Projekts liegt)</p>
<p>Auch das Modell wird über eine FactoryMethod geladen, da unterschiedliche Loader dahinterstecken können und das Erstellen ebenfalls ziemlich aufwendig ist.</p>
<p>Was mich jetzt etwas stört: loadModel und createBoundingSphereTree liefern jeweils ein mit new erzeugtes Objekt zurück. Man kann das Ergebnis in einen Smartptr verfrachten und ist zufrieden. Aber wie mache ich das meinem Benutzer klar, der meine Engine nutzt? Wenn der aufmerksam ist, wird er sich ja fragen, ob er den Speicher freigeben muss ohne zu wissen, dass Model das bereits erledigt (was ich bisher z.B. auch euch gegenüber nicht erwähnt habe).</p>
<p>Also wie löse ich die Problematik, dass sehr große mit new erzeugte Objekte über Funktionen zurückgegeben werden und der Nutzer das u.U. gar nicht weiß?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2091405</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2091405</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 11 Jul 2011 14:44:40 GMT</pubDate></item><item><title><![CDATA[Reply to Erstellung von Objekten und Zuweisung: Chic oder nicht? on Mon, 11 Jul 2011 21:41:56 GMT]]></title><description><![CDATA[<p>Warum nicht gleich Smart-Pointer zurückgeben? Hier ist wohl <code>unique_ptr</code> naheliegend. Im Gegensatz zu rohen Zeigern ist die Besitzsemantik bei einem Smart-Pointer normalerweise eindeutig, der Benutzer wird sich also nichts fragen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2091570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2091570</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 11 Jul 2011 21:41:56 GMT</pubDate></item><item><title><![CDATA[Reply to Erstellung von Objekten und Zuweisung: Chic oder nicht? on Tue, 12 Jul 2011 07:37:43 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Auch das Modell wird über eine FactoryMethod geladen, da unterschiedliche Loader dahinterstecken können und das Erstellen ebenfalls ziemlich aufwendig ist.</p>
<p>Was mich jetzt etwas stört: loadModel und createBoundingSphereTree liefern jeweils ein mit new erzeugtes Objekt zurück. Man kann das Ergebnis in einen Smartptr verfrachten und ist zufrieden. Aber wie mache ich das meinem Benutzer klar, der meine Engine nutzt? Wenn der aufmerksam ist, wird er sich ja fragen, ob er den Speicher freigeben muss ohne zu wissen, dass Model das bereits erledigt (was ich bisher z.B. auch euch gegenüber nicht erwähnt habe)</p>
</blockquote>
<p>Konstruktion und Destruktion müssen ja immer paarweise erfolgen. Das fängt an mit dem richtigen delete/delete[]/free zum new/new[]/malloc, hört dort aber noch lange nicht auf. Bei DLLs sollte Beispielsweise alles was in der DLL erzeugt wird, auch in der DLL zerstört werden. Wenn du die Konstruktion in einer Factory erledigst, sollte dort auch die Destruktion erfolgen. Die Factory weiß, wie sie ein Objekt konstruiert hat, muss also auch wissen, wie sie es wieder beseitigt. unique_ptr hat ein deleter-Template-Argument, d.h. du kannst dafür sorgen, dass zum Zerstören nicht delete sondern etwas anderes aufgerufen wird. Sprich: gib aus loadModel einen unique_ptr&lt;Model, ModelLoader::unloadModel&gt; zurück und alles ist super <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/2091636</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2091636</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 12 Jul 2011 07:37:43 GMT</pubDate></item><item><title><![CDATA[Reply to Erstellung von Objekten und Zuweisung: Chic oder nicht? on Tue, 12 Jul 2011 08:03:27 GMT]]></title><description><![CDATA[<p>Also ehrlich gesagt halte ich diese Symmetrie &quot;wer erzeugt, der löscht auch&quot; in meinen Programmen so-gut-wie nie ein.<br />
Hatte damit auch noch nie ein Problem. Die DLL Geschichte kann man z.B. dadurch entschärfen, dass man überall den selben Compiler und eine DLL Runtime verwendet.</p>
<p>Was den Returntyp der Factory angeht: unique_ptr finde ich auch gut. Es sei denn die ganze Engine arbeitet sowieso überall mit einem bestimmten Smart-Pointer, dann würde ich auch gleich genau so einen Smart-Pointer zurückgeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2091645</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2091645</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 12 Jul 2011 08:03:27 GMT</pubDate></item><item><title><![CDATA[Reply to Erstellung von Objekten und Zuweisung: Chic oder nicht? on Tue, 12 Jul 2011 08:34:24 GMT]]></title><description><![CDATA[<p>Die Smartpointer sind bis auf einige Ausnahmen in der Engine rar. An den anderen Stellen brauchte ich bisher nie Factorys und habe daher auch keine verwendet.</p>
<p>Dann noch eine Verständnisfrage: Ich hätte gedacht, der unique_ptr lässt sich nicht zurückgeben o.ä., habe jetzt aber gelesen, dass die Move-Semantik hier greift. Hätte irgendwie gedacht, das funktioniert nur für Container. Die Semantik nutzt man hier auch nur, weil man ganz klar von Kopie und Bewegung (Move) unterscheiden will/muss?</p>
<p>Wenn das funktioniert, gefällt mir die Variante natürlich sehr gut. Zum Löschen wird zur Zeit nichts weiter erfordert, weil das Datenladen zwar komplex ist, aber zum Entladen weit weniger Aufwand notwendig ist und dass alle Destrukturen hinbekommen.</p>
<p>Vielleicht noch gut zu wissen: die Hauptproblematik beim Laden besteht im Parsen von Dateien mit bestimmten Formaten. Das muss alles von Dateistruktur in Engine-Struktur (=meine Struktur) umgewandelt werden. Ist es einmal verankert ist das Ressourcen freigeben hingegen trivial. <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>Dann erscheint doch Folgendes ganz gut:</p>
<pre><code class="language-cpp">// ModelLoader.hpp

namespace Engine
{
    class Model;

    typedef unique_ptr&lt;Model&gt; ModelPtr;

    ModelPtr createModel(/* ... */);
}
</code></pre>
<p>Jetzt kann ich nachträglich noch einen Deletor einfügen, falls ich ihn denn wirklich brauchen sollte, wovon ich aber nicht ausgehe. (Und jetzt könnte die Diskussion zwischen euch (hustbaer und pumuckl) diesbzgl. wieder einsetzen :))</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2091656</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2091656</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 12 Jul 2011 08:34:24 GMT</pubDate></item><item><title><![CDATA[Reply to Erstellung von Objekten und Zuweisung: Chic oder nicht? on Tue, 12 Jul 2011 09:01:57 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Dann noch eine Verständnisfrage: Ich hätte gedacht, der unique_ptr lässt sich nicht zurückgeben o.ä., habe jetzt aber gelesen, dass die Move-Semantik hier greift. Hätte irgendwie gedacht, das funktioniert nur für Container. Die Semantik nutzt man hier auch nur, weil man ganz klar von Kopie und Bewegung (Move) unterscheiden will/muss?</p>
</blockquote>
<p>Nein, es funktioniert nicht nur für Container. Move-Semantik macht bei allem sinn, was irgendeine Ressource weitergeben will, d.h. A hat die Ressource und gibt sie an B weiter. Im Fall von Containern ist das der Speicher mit dem Inhalt der Container, damit nicht alles kopiert und sofort das original weggeworfen wird. Beim unique_ptr ists der Speicher mit dem enthaltenen Objekt, der <em>darf</em> nicht kopiert werden. Beim unique_ptr ist genau einer der Besitzer des Objekts auf dem Freispeicher. Kopieren ist daher verboten, sonst wären zwei die Besitzer oder es wäre eine unechte Kopie wie beim auto_ptr. Move-Semantik ist hier genau das Richtige, der Besitz vom einen unique_ptr wird an den nächsten weitergeschoben.</p>
<blockquote>
<p>Wenn das funktioniert, gefällt mir die Variante natürlich sehr gut. Zum Löschen wird zur Zeit nichts weiter erfordert, weil das Datenladen zwar komplex ist, aber zum Entladen weit weniger Aufwand notwendig ist und dass alle Destrukturen hinbekommen.</p>
<p>Vielleicht noch gut zu wissen: die Hauptproblematik beim Laden besteht im Parsen von Dateien mit bestimmten Formaten. Das muss alles von Dateistruktur in Engine-Struktur (=meine Struktur) umgewandelt werden. Ist es einmal verankert ist das Ressourcen freigeben hingegen trivial. <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>Dann erscheint doch Folgendes ganz gut:</p>
<pre><code class="language-cpp">// ModelLoader.hpp

namespace Engine
{
    class Model;

    typedef unique_ptr&lt;Model&gt; ModelPtr;

    ModelPtr createModel(/* ... */);
}
</code></pre>
<p>Jetzt kann ich nachträglich noch einen Deletor einfügen, falls ich ihn denn wirklich brauchen sollte, wovon ich aber nicht ausgehe. (Und jetzt könnte die Diskussion zwischen euch (hustbaer und pumuckl) diesbzgl. wieder einsetzen :))</p>
</blockquote>
<p>So in der Art hätte ichs mir auch vorgestellt. Den Deletor einzufügen ist trivial: einfach eine entsprechende Funktion schreiben und sie in den typedef mit aufnehmen. Wenn mehrere Objekte eine Referenz auf das selbe model haben können sollen ließe sich das noch ändern in shared/weak_ptr. Auch die haben deleter...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2091667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2091667</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 12 Jul 2011 09:01:57 GMT</pubDate></item></channel></rss>