<?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[Kompilierzeitprobleme mit modularer Programmierung]]></title><description><![CDATA[<p>Vor einiger Zeit habe ich <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-216286.html" rel="nofollow">hier</a> gefragt, welche Vorteile mehrere Übersetzungseinheiten bringen würden. Eine Antwort war dabei kürzere Kompilierzeit.</p>
<p>In letzter Zeit hab ich dieses Konzept der modularen Programmierung (mehrere CPP-Dateien, Aufteilung von Klassen in Header und Implementierung) durchgesetzt. Von der angeblichen Compilezeitreduktion hab ich allerdings nichts gespürt. Im Gegenteil.</p>
<p>Da ich mit verhältnismässig wenigen Dateien (je etwa 20 .h/.cpp) arbeite und viele Dateien einander benötigen und folglich pro Modul relativ viele Header eingebunden werden, braucht jedes Modul jetzt fast so lange wie der gesamte Code vorher (!). Das bedeutet, totale Kompilierzeit ist um die 20 Sekunden.</p>
<p>Und bevor jemand mit Designproblemen kommt: Ich habe mir das überlegt, ich benötige diese Header wirklich (es handelt sich um ein Spiel, wo z.B. Spielelemente wie Gegner, Waffen, Spieler etc. einander gegenseitig beeinträchtigen und dementsprechend die Klassen gegenseitig bekannt machen müssen).</p>
<p>Das Problem dabei ist, dass man auch kaum Zeit einsparen kann, wenn z.B. nur eine Übersetzungseinheit geändert wird, weil sich die Header in sehr vielen Modulen auswirken.</p>
<p>Naja, die Übersichtlichkeit ist vielleicht ein Vorteil, aber diese lange Kompilierzeit ist ziemlich demotivierend. Ist das immer so, oder einfach Pech in meinem Falle, weil viele Abhängigkeiten bestehen?</p>
<p>Und wird durch die Aufteilung auf mehrere CPP-Dateien der Code bzw. die ausführbare Datei stark grösser?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/220178/kompilierzeitprobleme-mit-modularer-programmierung</link><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Jul 2026 08:23:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/220178.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 12 Aug 2008 19:15:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Tue, 12 Aug 2008 19:15:25 GMT]]></title><description><![CDATA[<p>Vor einiger Zeit habe ich <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-216286.html" rel="nofollow">hier</a> gefragt, welche Vorteile mehrere Übersetzungseinheiten bringen würden. Eine Antwort war dabei kürzere Kompilierzeit.</p>
<p>In letzter Zeit hab ich dieses Konzept der modularen Programmierung (mehrere CPP-Dateien, Aufteilung von Klassen in Header und Implementierung) durchgesetzt. Von der angeblichen Compilezeitreduktion hab ich allerdings nichts gespürt. Im Gegenteil.</p>
<p>Da ich mit verhältnismässig wenigen Dateien (je etwa 20 .h/.cpp) arbeite und viele Dateien einander benötigen und folglich pro Modul relativ viele Header eingebunden werden, braucht jedes Modul jetzt fast so lange wie der gesamte Code vorher (!). Das bedeutet, totale Kompilierzeit ist um die 20 Sekunden.</p>
<p>Und bevor jemand mit Designproblemen kommt: Ich habe mir das überlegt, ich benötige diese Header wirklich (es handelt sich um ein Spiel, wo z.B. Spielelemente wie Gegner, Waffen, Spieler etc. einander gegenseitig beeinträchtigen und dementsprechend die Klassen gegenseitig bekannt machen müssen).</p>
<p>Das Problem dabei ist, dass man auch kaum Zeit einsparen kann, wenn z.B. nur eine Übersetzungseinheit geändert wird, weil sich die Header in sehr vielen Modulen auswirken.</p>
<p>Naja, die Übersichtlichkeit ist vielleicht ein Vorteil, aber diese lange Kompilierzeit ist ziemlich demotivierend. Ist das immer so, oder einfach Pech in meinem Falle, weil viele Abhängigkeiten bestehen?</p>
<p>Und wird durch die Aufteilung auf mehrere CPP-Dateien der Code bzw. die ausführbare Datei stark grösser?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563609</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563609</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 12 Aug 2008 19:15:25 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Tue, 12 Aug 2008 19:43:47 GMT]]></title><description><![CDATA[<p>Hallo</p>
<p>Zunächsteinmal kann man die Abhängigkeiten von <em>Headern</em> untereinander sehr wohl reduzzieren, indem man Forward Declarartions benutzt. Sinnvoll eingesetzt macht man dann im besten Fall nur noch Implementationen von Headern abhängig.</p>
<p>Wenn du natürlich ständig an zentralen Headerdateien etwas änderst, dann ist es kein Wunder das fast alle anderen Übersetzungseinheiten auch neu kompiliert werden müßen. In Headerdateien sollte nur das nötigste stehen, eben was als feststehendes Interface nach außen hin bekannt sein muß.</p>
<p>bis bald<br />
akari</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563620</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563620</guid><dc:creator><![CDATA[akari]]></dc:creator><pubDate>Tue, 12 Aug 2008 19:43:47 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Tue, 12 Aug 2008 19:45:49 GMT]]></title><description><![CDATA[<p>Außerdem gibt es bei einigen Compilern die Option, Headerdateien vorzukompilieren; wenn du das richtig einsetzt (und akaris Hinweis befolgst), sollte sich deine Kompilierzeit deutlich reduzieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563625</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563625</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Tue, 12 Aug 2008 19:45:49 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Tue, 12 Aug 2008 19:48:05 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Das Problem dabei ist, dass man auch kaum Zeit einsparen kann, wenn z.B. nur eine Übersetzungseinheit geändert wird, weil sich die Header in sehr vielen Modulen auswirken.</p>
</blockquote>
<p>Wenn du nur eine Übersetzungseinheit (.cpp-Datei) änderst, musst du auch nur diese neu kompilieren. Nur wenn du einen Header änderst, musst du alle abhängigen ÜEn neu kompilieren.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Naja, die Übersichtlichkeit ist vielleicht ein Vorteil, aber diese lange Kompilierzeit ist ziemlich demotivierend. Ist das immer so, oder einfach Pech in meinem Falle, weil viele Abhängigkeiten bestehen?</p>
</blockquote>
<p>Das ist kein Pech, sondern etwas, dass du durch Design beheben kannst (auch wenn du das nicht hören willst).</p>
<p>Wenn du ein ordentliches Design hast, sollten die Schnittstellen der Klassen schon längst feststehen. Mit dem Pimpl-Idiom kannst du die Implementierung von der Schnittstelle trennen. Damit musst du nur noch dann mehrere ÜEn kompilieren, wenn sich eine Schnittstelle ändert. Und das sollte nicht passieren (s.o.).</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Und wird durch die Aufteilung auf mehrere CPP-Dateien der Code bzw. die ausführbare Datei stark grösser?</p>
</blockquote>
<p>Nein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563626</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563626</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Tue, 12 Aug 2008 19:48:05 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Tue, 12 Aug 2008 19:53:48 GMT]]></title><description><![CDATA[<p>Danke für eure Antworten.</p>
<p><strong>@ akari:</strong><br />
Was Forward Declarations betrifft: Da hab ich auch einige drin. Jedoch impliziert das immer, dass man als Member nur Zeiger oder Referenzen haben kann. Das führt dazu, dass ich für jede kleine Klasse, die mehrfach vorkommen kann, einen eigenen Kopierkonstruktor, Destruktor und Zuweisungsoperator implementieren muss - was meiner Ansicht nach nicht gerade optimal ist. Zudem hat man mit Zeigern eh viele Probleme, also wenn man etwas gerade so gut mit Stackvariablen erledigen kann, tut man das meiner Ansicht nach besser.</p>
<p>Und in den Headerdateien hab ich eigentlich auch nur das Nötigste (eben die Klassendefinition selber + eventuelle globale Funktions- bzw. Variablendeklarationen).</p>
<p><strong>@ audacia:</strong><br />
Aber das nützt doch auch nur, wenn man die Headerdateien nicht ändert. Bei einem Spielaufbau kommt es relativ häufig vor, dass man merkt &quot;ah da muss ich noch eine Funktion hinzufügen, und dort fehlt ein spezifischer Konstruktor&quot;...</p>
<p><strong>@ MFK:</strong><br />
Wie gesagt, bei meinem Design sehe ich keine grossen Möglichkeiten zur Optimierung mehr (zu Vorwärtsdeklarationen siehe oben).<br />
Und weshalb wird die ausführbare Datei nicht stark grösser? Wird der Code vom Linker wieder schön zusammengeführt und vereinheitlicht? Sorry da kenn ich mich nicht sehr genau aus...</p>
<p>Wie macht ihr das eigentlich? <code>#include</code> -Direktiven fast nur in CPP-Dateien?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563630</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563630</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 12 Aug 2008 19:53:48 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Wed, 13 Aug 2008 05:28:09 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Jedoch impliziert das immer, dass man als Member nur Zeiger oder Referenzen haben kann. Das führt dazu, dass ich für jede kleine Klasse, die mehrfach vorkommen kann, einen eigenen Kopierkonstruktor, Destruktor und Zuweisungsoperator implementieren muss - was meiner Ansicht nach nicht gerade optimal ist. Zudem hat man mit Zeigern eh viele Probleme, also wenn man etwas gerade so gut mit Stackvariablen erledigen kann, tut man das meiner Ansicht nach besser.</p>
</blockquote>
<p>Hast du dir das Pimpl-Idiom mal angesehen?</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Aber das nützt doch auch nur, wenn man die Headerdateien nicht ändert. Bei einem Spielaufbau kommt es relativ häufig vor, dass man merkt &quot;ah da muss ich noch eine Funktion hinzufügen, und dort fehlt ein spezifischer Konstruktor&quot;...</p>
</blockquote>
<p>Das klingt danach, als hättest du angefangen zu programmieren, bevor das Design fertig war. Das sollte nicht &quot;relativ häufig&quot; vorkommen, sondern ziemlich selten. Wenn du natürlich Planung und Implementierung &quot;gleichzeitig&quot; machst, solltest du dich über erhöhte Kompilierungszeiten nicht wundern.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Und weshalb wird die ausführbare Datei nicht stark grösser? Wird der Code vom Linker wieder schön zusammengeführt und vereinheitlicht?</p>
</blockquote>
<p>Erklär doch mal, warum du glaubst, dass der Code überhaupt nennenswert größer werden sollte. Von Inline-Funktionen mal abgesehen, steckt doch jede Funktion in genau einer Übersetzungseinheit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563723</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563723</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Wed, 13 Aug 2008 05:28:09 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Wed, 13 Aug 2008 06:55:11 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Wie macht ihr das eigentlich? <code>#include</code> -Direktiven fast nur in CPP-Dateien?</p>
</blockquote>
<p>Sollte nicht durch saubere Trennung der Klassen mit Schnittstellen vermieden werden, dass du in Headerdateien andere Header einbindest?</p>
<p>In der Headerdatei sollte doch dann nur die Klasse als Schnittstelle stehen und bei der Implementation der Klassenmethoden (in einer cpp Datei) sollte dann auf andere Header verwiesen werden. Sonst bindest du den anderen Header immer mit ein, wenn du eine bestimmte Headerdatei einbindest, die andere Headerdateien includiert.</p>
<p>Also so weit ich weiß, sollte man #include-Direktiven möglichst nur in cpp-Dateien verwenden. Sonst mal das Design überdenken...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1563743</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1563743</guid><dc:creator><![CDATA[#include in Header]]></dc:creator><pubDate>Wed, 13 Aug 2008 06:55:11 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Wed, 13 Aug 2008 15:12:01 GMT]]></title><description><![CDATA[<p>MFK schrieb:</p>
<blockquote>
<p>Hast du dir das Pimpl-Idiom mal angesehen?</p>
</blockquote>
<p>Ich hab es mir einmal angeschaut (auf <a href="http://en.wikibooks.org" rel="nofollow">en.wikibooks.org</a>), aber irgendwie bin ich nicht so richtig davon überzeugt. Erstens müsste ich dann für jede Klasse noch eine separate mit dem Body erzeugen, und zweitens ist es gerade bei meinen Anwendungen nicht so extrem tragisch, wenn man als Anwender etwas sieht, das eigentlich zur Implementation gehört. Aber der Vorteil der Kompilierungsverkürzung ist natürlich schon vorhanden.</p>
<p>MFK schrieb:</p>
<blockquote>
<p>Das klingt danach, als hättest du angefangen zu programmieren, bevor das Design fertig war. Das sollte nicht &quot;relativ häufig&quot; vorkommen, sondern ziemlich selten. Wenn du natürlich Planung und Implementierung &quot;gleichzeitig&quot; machst, solltest du dich über erhöhte Kompilierungszeiten nicht wundern.</p>
</blockquote>
<p>Nein, das grobe Design stand eigentlich schon vorher. Ich weiss nicht, ob du selber schon Spiele programmiert hast, aber es kann schon vorkommen, dass man mitten in der Programmierung merkt, dass man noch ein neues Spielelement hinzufügen will, welches das halbe Spielkonzept über den Haufen wirft. Aber du hast Recht, häufig geschieht das eigentlich nicht.</p>
<p>MFK schrieb:</p>
<blockquote>
<p>Erklär doch mal, warum du glaubst, dass der Code überhaupt nennenswert größer werden sollte. Von Inline-Funktionen mal abgesehen, steckt doch jede Funktion in genau einer Übersetzungseinheit.</p>
</blockquote>
<p>Naja, ich war mir nur nicht sicher, weil ich mich eben nicht so gut auskenne bei der Codegenerierung und Linkage... Aber dann brauche ich mir ja keine Gedanken darum zu machen.</p>
<p>#include in Header schrieb:</p>
<blockquote>
<p>Also so weit ich weiß, sollte man #include-Direktiven möglichst nur in cpp-Dateien verwenden. Sonst mal das Design überdenken...</p>
</blockquote>
<p>Ich meine nur, wenn man z.B. eine Klasse hat, die als Member Objekte von anderen Klassen besitzt, dann kann man die benötigten Klassen doch gerade in dieser Headerdatei einbinden, oder?</p>
<p>Aber die ganze Thematik scheint mir doch schwerwiegender, als ich zu Beginn dachte. Früher hatte ich immer eine CPP-Datei, und alles andere in Header ausgelagert. Da brauchte ich mir weder Gedanken um Linker-Mehrfachdefinitionen, noch um erhöhte Kompilierzeiten, spezielles Einbinden von Headern oder Pimpl-Idioms zu machen. Klar war es vielleicht nicht das beste Design, aber immerhin kam man noch zum Programmieren <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>Es ist nicht so, dass ich den Vorteil der modular-objektorientierten Programmierung nicht sehe. Ich kann durchaus nachvollziehen, dass man bei wirklich grossen Projekten (z.B. in der Softwareentwicklung) grossen Nutzen davon hat, aber mir persönlich scheint es eher mehr Probleme zu bereiten...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564175</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564175</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 13 Aug 2008 15:12:01 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 09:16:11 GMT]]></title><description><![CDATA[<p>Trotzdem kann ich bei dir nicht nachvollziehen, warum du bei modularer Programmierung größere Kompilierzeiten hast als bei einer Datei.<br />
Denn bei Änderung an einer Datei müßte ja der ganze Code neu kompiliert werden (und dies jedesmal, anstatt nur einige wenige kleinere Dateien).</p>
<p>Welchen Compiler setzt du denn ein, evtl. solltest du mal - wie vorgeschlagen - vorkompilierte Headerdateien einsetzen?</p>
<p>Vllt. könntest du ja mal dein Klassendesign exemplarisch hier aufzeigen, d.h. die Header und deren Includes.</p>
<p>Aus</p>
<blockquote>
<p>Das führt dazu, dass ich für jede kleine Klasse, die mehrfach vorkommen kann, einen eigenen Kopierkonstruktor, Destruktor und Zuweisungsoperator implementieren muss - was meiner Ansicht nach nicht gerade optimal ist.</p>
</blockquote>
<p>schließe ich, daß du noch einigen Nachholbedarf beim Design und deren Anwendung in C++ hast, denn das Verwenden von eingebetteten Objekten führt ja zu Kopien, so daß keine Eindeutigkeit der Objekte mehr gewährleistet ist.</p>
<p>Ein gutes Design führt oftmals insgesamt zu kleinerem Code (trotz expliziter Implementierung bestimmter Methoden).</p>
<p>Da ich 5 Jahre in einer Computerspiele-Firma gearbeitet habe, kenne ich mich mit den Problematiken bei großen Spieleprojekten sehr gut aus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564539</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564539</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Thu, 14 Aug 2008 09:16:11 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 16:01:15 GMT]]></title><description><![CDATA[<p>Th69 schrieb:</p>
<blockquote>
<p>Trotzdem kann ich bei dir nicht nachvollziehen, warum du bei modularer Programmierung größere Kompilierzeiten hast als bei einer Datei.<br />
Denn bei Änderung an einer Datei müßte ja der ganze Code neu kompiliert werden (und dies jedesmal, anstatt nur einige wenige kleinere Dateien).</p>
</blockquote>
<p>Ja, aber wie gesagt gibt es bei mir relativ viele Module, die voneinander abhängen (z.B. Spieler - Gegner, Spieler - Game, etc.)... Siehe dazu unten das Design.</p>
<p>Th89 schrieb:</p>
<blockquote>
<p>Vllt. könntest du ja mal dein Klassendesign exemplarisch hier aufzeigen, d.h. die Header und deren Includes.</p>
</blockquote>
<p>Gut möglich, dass das Design so nicht gut ist, aber damit hab ich eben noch nicht so grosse Erfahrung (bzw. das ist mein erstes Spiel, wo ich richtig modular programmiere und aufs Design achte).</p>
<p>Also es handelt sich um ein Jump'n'Run. Ich muss noch erwähnen, dass die Klassen <code>Enemy</code> und <code>Weapon</code> noch nicht implementiert sind, ich hab sie jedoch so im Design vorgesehen.</p>
<p>Zuerst mal die Vererbungshierarchie:</p>
<pre><code>[b]Master[/b] (verwaltet alles)
        im Moment noch alles statische Member,
         soll jedoch noch Singleton werden
        sozusagen global, von überall zugreifbar

           [b]Surface[/b] (Oberfläche)
                     |
   +----------+------+-------+--------+
   |          |              |        |
[b]MainMenu[/b]   [b]InfoMenu[/b]   ..    [b]Game[/b]    [b]Editor[/b]

         [b]Object[/b] (Spielelemente,                      [b]Tile[/b]
      die Kollision berücksichtigen)           (Bausteine der Welt)
                 |
  +--------------+---------------+
  |              |               |
[b]Player[/b]         [b]Enemy[/b]          [b]Weapon[/b]
                        (abgefeuerte Waffen)
</code></pre>
<p>Zusätzlich noch einige weniger relevante Klassen.</p>
<p>Hier die Membertypen von wichtigen Klassen:</p>
<pre><code>Master
--&gt; Surface* (Basisklassenzeiger (Polymorphie))
--&gt; Grafikklassen (Fenster, Event, etc.), die überall benötigt werden

Game
--&gt; Player
--&gt; Enemy
--&gt; Weapon
--&gt; Tile
</code></pre>
<p>Nun ist es so, dass Kollisionsabfragen in <code>Object</code> passieren, d.h. da werden schon mal die Klassen <code>Tile</code> und <code>Game</code> (aktuelle Oberfläche) benötigt. Bei den Klassen <code>Player</code> , <code>Enemy</code> und <code>Weapon</code> muss ich wahrscheinlich eine Dreiecksabhängigkeit einrichten, weil sich diese Klassen jeweils gegenseitig beeinträchtigen können.<br />
<code>Game</code> selber benötigt natürlich alle Klassen, die Typen der Member sind.<br />
Was ein Problem darstellt, ist die Tatsache, dass z.B. <code>Player</code> indirekt über die Basisklasse <code>Object</code> auf <code>Game</code> Zugriff haben muss, um z.B. Kollisionsabfragen mit den Tiles zu handhaben. Ich habe das mit einem Zeiger gelöst, jedoch hab ich momentan das Problem, dass eine Vorwärtsdeklaration nicht ausreicht, weil ein <code>dynamic_cast&lt;Game*&gt;(Surface*)</code> durchgeführt werden muss. Aber das lässt sich evtl. dadurch lösen, dass beim Erstellen der <code>Player</code> -Instanz ein Zeiger auf <code>Game</code> übergeben wird. Was wiederum nicht geht, weil im Konstruktor von <code>Game</code> ja auch <code>Player</code> konstruiert wird, und der <code>this</code> -Zeiger von <code>Game</code> zu diesem Zeitpunkt noch auf die Basisklasse <code>Surface</code> verweist... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Grundsätzlich wäre fast alles mit Vorwärtsdeklarationen und Zeigern als Member zu lösen. Was ich jedoch unnötig finde, weil auf ich eigene Speicherverwaltung lieber verzichte, wo sichs vermeiden lässt (und wie gesagt auf <em>The Big Three</em>). Oder ist das die gängige Variante (Pimpl scheint mir arg übertrieben für mein verhältnismässig kleines Spiel)?</p>
<p>Dazu:</p>
<p>Th89 schrieb:</p>
<blockquote>
<p>Aus</p>
<blockquote>
<p>Das führt dazu, dass ich für jede kleine Klasse, die mehrfach vorkommen kann, einen eigenen Kopierkonstruktor, Destruktor und Zuweisungsoperator implementieren muss - was meiner Ansicht nach nicht gerade optimal ist.</p>
</blockquote>
<p>schließe ich, daß du noch einigen Nachholbedarf beim Design und deren Anwendung in C++ hast</p>
</blockquote>
<p>Das will ich auch nicht bestreiten <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 />
Aber was ist denn daran so falsch?<br />
Und was meinst du genau mit folgender Aussage?</p>
<p>Th89 schrieb:</p>
<blockquote>
<p>denn das Verwenden von eingebetteten Objekten führt ja zu Kopien, so daß keine Eindeutigkeit der Objekte mehr gewährleistet ist.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1564884</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564884</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 14 Aug 2008 16:01:15 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 16:25:41 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Was Forward Declarations betrifft: Da hab ich auch einige drin. Jedoch impliziert das immer, dass man als Member nur Zeiger oder Referenzen haben kann. Das führt dazu, dass ich für jede kleine Klasse, die mehrfach vorkommen kann, einen eigenen Kopierkonstruktor, Destruktor und Zuweisungsoperator implementieren muss - was meiner Ansicht nach nicht gerade optimal ist.</p>
</blockquote>
<p>Warum sollte man wegen Forward Declaration mehr Kopierkonstruktor, Destruktor und Zuweisungsoperator implementieren müssen? Thema Smartpointer...</p>
<blockquote>
<p>shared_ptr&lt;T&gt; kann für einen unvollständigen Typ T verwendet werden:</p>
<pre><code class="language-cpp">class X; // forward declaration
shared_ptr&lt;X&gt; pX; // &quot;X *&quot;
</code></pre>
<p>Zum Dereferenzieren und Freigeben von pX muss X aber vollständig bekannt sein - boost prüft das und wirft andernfalls eine Compile-Fehlermeldung.</p>
</blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Wie macht ihr das eigentlich? <code>#include</code> -Direktiven fast nur in CPP-Dateien?</p>
</blockquote>
<p>In meinen privaten Projekten: Ja.<br />
In Projekten an der Arbeit: Kommt auf den Codestil an, auch wenn ich immer versuchen werde, soviel wie möglich in den Source zu ziehen.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564900</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564900</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 14 Aug 2008 16:25:41 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 20:04:34 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Master (verwaltet alles)<br />
im Moment noch alles statische Member,<br />
soll jedoch noch Singleton werden<br />
sozusagen global, von überall zugreifbar</p>
</blockquote>
<p>Hmm. Das würde ich schon mal anderst lösen. Mach da lieber ein Objekt draus, dass du dann direkt in der main initialisierst und hald einen Zeiger, oder eine Referenz an die restlichen Klassen übergibst, damit du darauf zugreifen kannst.</p>
<p>Fände ich sauberer, als da mit Singletons zu arbeiten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565010</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565010</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 14 Aug 2008 20:04:34 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 20:07:59 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Master (verwaltet alles)<br />
im Moment noch alles statische Member,<br />
soll jedoch noch Singleton werden<br />
sozusagen global, von überall zugreifbar</p>
</blockquote>
<p>Hmm. Das würde ich schon mal anderst lösen. Mach da lieber ein Objekt draus, dass du dann direkt in der main initialisierst und hald einen Zeiger, oder eine Referenz an die restlichen Klassen übergibst, damit du darauf zugreifen kannst.</p>
<p>Fände ich sauberer, als da mit Singletons zu arbeiten.</p>
</blockquote>
<p>Das hättest du anders zitieren sollen. So macht es den Eindruck, als wollte Nexus sich als Dichter betätigen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565016</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 14 Aug 2008 20:07:59 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 20:11:37 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Das hättest du anders zitieren sollen. So macht es den Eindruck, als wollte Nexus sich als Dichter betätigen.</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Entweder ich verstehe dich falsch, oder du hast ein Smylie vergessen. <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/1565019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565019</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 14 Aug 2008 20:11:37 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 20:12:12 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Fände ich sauberer, als da mit Singletons zu arbeiten.</p>
</blockquote>
<p>Ich finde das hört sich schon ziemlich nach Singleton an. Überall Zeiger rumzureichen finde ich da viel viel ekliger.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Grundsätzlich wäre fast alles mit Vorwärtsdeklarationen und Zeigern als Member zu lösen.</p>
</blockquote>
<p>Mach das bloß nicht. Ist imo unsinning, genauso mit Smartpointern. Ich würde nie &quot;reine&quot; Membervariablen gegen Kompilierzeit eintauschen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565020</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565020</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Thu, 14 Aug 2008 20:12:12 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 20:22:24 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>Das hättest du anders zitieren sollen. So macht es den Eindruck, als wollte Nexus sich als Dichter betätigen.</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Entweder ich verstehe dich falsch, oder du hast ein Smylie vergessen. <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>
</blockquote>
<p>Du irrst, indem du recht hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565023</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565023</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 14 Aug 2008 20:22:24 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 20:32:26 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>drakon schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>Das hättest du anders zitieren sollen. So macht es den Eindruck, als wollte Nexus sich als Dichter betätigen.</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Entweder ich verstehe dich falsch, oder du hast ein Smylie vergessen. <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>
</blockquote>
<p>Du irrst, indem du recht hast.</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565030</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 14 Aug 2008 20:32:26 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 21:19:13 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Das hättest du anders zitieren sollen. So macht es den Eindruck, als wollte Nexus sich als Dichter betätigen.</p>
</blockquote>
<p>Dass man es als Gedicht erkennen könnte, war eigentlich nie meine Absicht - aber meine stichwortartige Beschreibung kommt da halt schon nahe <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>Badestrand schrieb:</p>
<blockquote>
<p>drakon schrieb:</p>
<blockquote>
<p>Fände ich sauberer, als da mit Singletons zu arbeiten.</p>
</blockquote>
<p>Ich finde das hört sich schon ziemlich nach Singleton an. Überall Zeiger rumzureichen finde ich da viel viel ekliger.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Grundsätzlich wäre fast alles mit Vorwärtsdeklarationen und Zeigern als Member zu lösen.</p>
</blockquote>
<p>Mach das bloß nicht. Ist imo unsinning, genauso mit Smartpointern. Ich würde nie &quot;reine&quot; Membervariablen gegen Kompilierzeit eintauschen.</p>
</blockquote>
<p>Puh, endlich mal jemand, der das Ganze so sieht wie ich <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 />
Was das Zeiger-Rumreichen betrifft, wäre das wirklich total eklig, da dann jede Funktion, die entweder Eingaben oder Bildschirmausgaben handhabt, noch einen zusätzlichen Parameter hätte (oder jede Klasse noch einen zusätzlichen Zeiger). Zum Teil wären auch noch ganz andere Funktionen betroffen, weil z.B. auch eine Instanz einer Zufallsgeneratorklasse in <code>Master</code> steht. Das würde sich hinten und vorne nicht lohnen.</p>
<p>Naja, ich hab mich einfach gewundert; wenn man beginnt, modular zu programmieren, sind plötzlich wieder Unmengen &quot;Hilfsmittel&quot; erforderlich, dass man es nur schafft, nicht schlechtere Voraussetzungen als bei nicht-modularer Programmierung zu haben... Wahrscheinlich nehm ich doch lieber die längere Kompilierzeit in Kauf...</p>
<p>Ach ja, noch was: Gibt es so was wie meine Masterklasse häufig in der Praxis? Ich finde es sehr praktisch, da ich in <code>main()</code> gerade mal zwei Anweisungen habe. Das Unschöne ist vielleicht, dass <code>Master</code> nur statische Member und Methoden hat, aber wie gesagt mach ich da vielleicht noch ein Singleton draus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565046</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565046</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 14 Aug 2008 21:19:13 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 21:24:52 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Naja, ich hab mich einfach gewundert; wenn man beginnt, modular zu programmieren, sind plötzlich wieder Unmengen &quot;Hilfsmittel&quot; erforderlich, dass man es nur schafft, nicht schlechtere Voraussetzungen als bei nicht-modularer Programmierung zu haben... Wahrscheinlich nehm ich doch lieber die längere Kompilierzeit in Kauf...</p>
</blockquote>
<p>Was du aber bedenken solltest: In der Anfangsphase wo man viele Interfaces aendert und oft nur mit mockups herumwirft und jedweder code total instabil (aus aenderungssicht - nicht bug-sicht) ist, sind mehrere uebersetzungseinheiten natuerlich doof, da so das linken laenger dauert.</p>
<p>sobald du aber einen stand erreicht hast wo ein teil des codes interface-stabil ist, sinken die compiletimes rapide. denk einfach nur daran, dass du ja einen grossteil der dateien nachdem sie einmal fertig sind kaum noch anfasst. am anfang, wo du aber jede datei dauernd aenderst - ists natuerlich etwas stoerend.</p>
<p>und auch aktuell, also trotz grossem recompile kann ich mir nicht vorstellen dass die compilezeiten soviel groesser sind. denn alles was mehr gemacht wird sind mehrmals header parsen -&gt; und das laesst sich mit precompiled headers sogar umgehen.</p>
<p>wenn du compilezeiten extrem senken willst, dann schau dir das pimpl-idiom an. ich bin kein grosser fan davon, wenn es aber um reduzierung von abhaengigkeiten geht ist es einfach super.</p>
<p>20 sekunden recompile deutet auf entweder einen sehr langsamen rechner hin oder auf viel code. und bei viel code: warum aenderst du die zentralen stellen dauernd?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565051</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565051</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 14 Aug 2008 21:24:52 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 21:56:13 GMT]]></title><description><![CDATA[<blockquote>
<p>und bei viel code: warum aenderst du die zentralen stellen dauernd?</p>
</blockquote>
<p>:p</p>
<p>Weisst du, was mir da manchmal passiert?<br />
Ich schaue mal ein wenig im Core, ob alles stimmt usw. Und aus reiner Gewohnheit mache ich da auch aus dem Reflex raus ctrl+s.. Und ich bemerke meinen Fehler auch sogleich beim drücken. *grml*<br />
Lösung: ctrl+F7 und mal was trinken gehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565065</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 14 Aug 2008 21:56:13 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 22:21:32 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<blockquote>
<p>und bei viel code: warum aenderst du die zentralen stellen dauernd?</p>
</blockquote>
<p>:p</p>
<p>Weisst du, was mir da manchmal passiert?<br />
Ich schaue mal ein wenig im Core, ob alles stimmt usw. Und aus reiner Gewohnheit mache ich da auch aus dem Reflex raus ctrl+s.. Und ich bemerke meinen Fehler auch sogleich beim drücken. *grml*<br />
Lösung: ctrl+F7 und mal was trinken gehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
</blockquote>
<p>dann ist dein editor komisch... wenn es keine aenderung gibt, sollte er die datei nicht modifizieren, auch bei einem ctrl+s nicht...</p>
<p>aber klar, sowas passiert mal dass man aus versehen eine zentrale datei unnoetigerweise &quot;aendert&quot; - aber das ist hoffentlich ausnahme und nicht regel <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/1565072</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565072</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 14 Aug 2008 22:21:32 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 22:24:33 GMT]]></title><description><![CDATA[<blockquote>
<p>dann ist dein editor komisch... wenn es keine aenderung gibt, sollte er die datei nicht modifizieren, auch bei einem ctrl+s nicht...</p>
<p>aber klar, sowas passiert mal dass man aus versehen eine zentrale datei unnoetigerweise &quot;aendert&quot; - aber das ist hoffentlich ausnahme und nicht regel</p>
</blockquote>
<p>Meist ist hald so, dass ich dennoch eine Taste drücke und dann speichere.. <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>Ja, ich schaue schon, dass das nicht all zu oft passiert. Es ist in der Tat recht mühsam nacher alles neu compilen zu müssen.. <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/1565073</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565073</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 14 Aug 2008 22:24:33 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 22:26:47 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Nun ist es so, dass Kollisionsabfragen in <code>Object</code> passieren, d.h. da werden schon mal die Klassen <code>Tile</code> und <code>Game</code> (aktuelle Oberfläche) benötigt.</p>
</blockquote>
<p>Also wenn schon würde ich Tile auch von Object ableiten und somit Tile auch als Kollisionobjekt ansehen. In der Klasse Object gibt es eine Methode, welche ein anderes Object annimmt und dann die Kollisionsabfrage ausführt.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Bei den Klassen <code>Player</code> , <code>Enemy</code> und <code>Weapon</code> muss ich wahrscheinlich eine Dreiecksabhängigkeit einrichten, weil sich diese Klassen jeweils gegenseitig beeinträchtigen können.</p>
</blockquote>
<p>Wird wohl nicht nötig sein, zumindest nicht in den Headern. Da kannst du überall Forward Declaration anwenden.<br />
Du wirst ja wohl kaum ein Player, Enemy oder Weapon kopieren wollen. Von überall her, wo du eine Instanz auf den Player, Enemy oder Weapon übergeben tust, soll es ja auch die gleiche sein. Also wirst du in erster Linie Zeiger herumreichen. Vor allem auch, weil du die Spieler, Gegner und Waffen auf dem Heap erstellen wirst. Und es sicher Möglichkeiten gibt, dass es keine Gegner, keine Waffen oder keine Spieler hat, also Nullzeiger.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p><code>Game</code> selber benötigt natürlich alle Klassen, die Typen der Member sind.</p>
</blockquote>
<p>Kommt drauf an, wie zentral du Game gestaltest. Vergiss nicht, dass man in Module auslagern sollte. Man kann auch Funktionsweisen oder Handlungen in Objekte packen, auch Beschreibungen sind möglich. Oder anders ausgedrückt:<br />
Nicht nur Nomen sind Objekte, sondern auch Adjektive, Verben, Adverben, Pronomen und was es sonst noch alles gibt <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>Nexus schrieb:</p>
<blockquote>
<p>Was ein Problem darstellt, ist die Tatsache, dass z.B. <code>Player</code> indirekt über die Basisklasse <code>Object</code> auf <code>Game</code> Zugriff haben muss, um z.B. Kollisionsabfragen mit den Tiles zu handhaben.</p>
</blockquote>
<p>Das leuchtet mir überhaupt nicht ein. Wieso kann der Player nicht direkt mit den Tiles interagieren? Game sollte höchstens den Player verschieben oder sowas ähnliches.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Was wiederum nicht geht, weil im Konstruktor von <code>Game</code> ja auch <code>Player</code> konstruiert wird, und der <code>this</code> -Zeiger von <code>Game</code> zu diesem Zeitpunkt noch auf die Basisklasse <code>Surface</code> verweist... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
</blockquote>
<p>Ah, da haben wir wieder so ein Problem. Du erstellst den Player als Eigenschaft von Game. Aber ist er das wirklich? Ich finde das irgendwie nicht. Einem Game Objekt sollte ein Player Objekt zugewiesen sein, vielleicht auch mehrere, aber es sollte den Player sicher nicht besitzen.<br />
Ein Spieler sollte meiner Meinung nach anderswo erstellt und dem Spiel dann übergeben werden.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Grundsätzlich wäre fast alles mit Vorwärtsdeklarationen und Zeigern als Member zu lösen. Was ich jedoch unnötig finde, weil auf ich eigene Speicherverwaltung lieber verzichte, wo sichs vermeiden lässt (und wie gesagt auf <em>The Big Three</em>).</p>
</blockquote>
<p>Auf &quot;The Big Three&quot; verzichtest du, in dem du Zeiger verwendest. Aber wenn du möglichst Zeiger meiden willst, weil du Angst vor der eigenen Speicherverwaltung hast, dann solltest du vielleicht eine andere Sprache wählen? C# oder Java? Bei C++ sind ja gerade solche Dinge ganz entscheidend und vieles wird darüber aufgebaut. Man verzichtet einfach auf einen ganz entscheidenden Teil der Sprache, wenn man keine eigene Speicherverwaltung einsetzt. Shared Pointer und ähnliches sollten nur Hilfskonstrukte für gewisse Situationen sein, aber nicht für alles.</p>
<p>Ich hoffe ich konnte dir etwas helfen. Vor allem überwinde deine Angst vor der Speicherverwaltung!</p>
<p>Eine &quot;Master-Option&quot;-Klasse, mache ich höchst selten. Das hat den einfach Grund, dass wenn man die Sache genügend aufsplittet in Objekte und Module, es irgendwann keine Option geben wird, welche für alle oder mehr als die Hälfte gilt. Man sollte zudem, meiner Meinung nach, nicht in solchen Dimensionen denken. Wenn eine Option verändert wird, dann betrifft das direkt entsprechende Objekte und dort sollten die Eigenschaften entsprechend gesetzt werden. Man sollte nicht Optionen zusammenschaufeln und in eine gemeinsame Klasse verfrachten. Ausser das sie Optionen sind, haben diese nämlich nichts gemeinsam!</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565074</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565074</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 14 Aug 2008 22:26:47 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Thu, 14 Aug 2008 23:45:17 GMT]]></title><description><![CDATA[<p>Vielen Dank für die hilfreichen Antworten! Es ist wirklich nett, wie ihr euch Zeit nehmt!</p>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Was du aber bedenken solltest: In der Anfangsphase [...] sind mehrere uebersetzungseinheiten natuerlich doof, da so das linken laenger dauert.<br />
sobald du aber einen stand erreicht hast wo ein teil des codes interface-stabil ist, sinken die compiletimes rapide.</p>
</blockquote>
<p>Hmm, das hat in der Tat was, daran hab ich eigentlich gar nicht gedacht <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>Shade Of Mine schrieb:</p>
<blockquote>
<p>20 sekunden recompile deutet auf entweder einen sehr langsamen rechner hin oder auf viel code. und bei viel code: warum aenderst du die zentralen stellen dauernd?</p>
</blockquote>
<p>Nein, ich denke nicht, dass der Rechner zu langsam ist. Eher die zweite Möglichkeit. Und wie gesagt lassen sich häufige Änderungen nicht immer umgehen, weil man plötzlich Details bemerkt oder neue Features hinzufügen will, die man vorher noch nicht eingeplant hat. Aber es stimmt schon, ich sollte mich vielleicht ein bisschen einschränken mit zentralen Änderungen.</p>
<p>drakon schrieb:</p>
<blockquote>
<p>Lösung: ctrl+F7 und mal was trinken gehen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
</blockquote>
<p>Hast du demnach auch das Problem mit langen Kompilierzeiten? Oder sind deine Projekte einfach so riesig? <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>Dravere schrieb:</p>
<blockquote>
<p>Also wenn schon würde ich Tile auch von Object ableiten und somit Tile auch als Kollisionobjekt ansehen. In der Klasse Object gibt es eine Methode, welche ein anderes Object annimmt und dann die Kollisionsabfrage ausführt.</p>
</blockquote>
<p>Nein, dann würde es von der Logik her keinen Sinn mehr machen. Ein Tile ist ja ein fester Bestandteil der Welt, d.h. es kann nur rasterförmig ausgerichtet sein (eben in einer Tilemap) und bewegt sich nicht. Objekte wie der Spieler oder abgefeuerte Waffen hingegen sind mobil und reagieren auf Kollision mit der Welt (also den Tiles).</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Bei den Klassen <code>Player</code> , <code>Enemy</code> und <code>Weapon</code> muss ich wahrscheinlich eine Dreiecksabhängigkeit einrichten, weil sich diese Klassen jeweils gegenseitig beeinträchtigen können.</p>
</blockquote>
<p>Wird wohl nicht nötig sein, zumindest nicht in den Headern. Da kannst du überall Forward Declaration anwenden.<br />
Du wirst ja wohl kaum ein Player, Enemy oder Weapon kopieren wollen. Von überall her, wo du eine Instanz auf den Player, Enemy oder Weapon übergeben tust, soll es ja auch die gleiche sein. Also wirst du in erster Linie Zeiger herumreichen. Vor allem auch, weil du die Spieler, Gegner und Waffen auf dem Heap erstellen wirst. Und es sicher Möglichkeiten gibt, dass es keine Gegner, keine Waffen oder keine Spieler hat, also Nullzeiger.</p>
</blockquote>
<p>Ja, also momentan verwalte ich diese Klassen in STL-Containern innerhalb von <code>Game</code> (die eben leer sind falls kein entsprechendes Objekt existiert). Falls es etwas rumzureichen gibt, benutze ich eher Referenzen. Aber das muss ich eh noch ausbauen, jetzt wird z.B. auf die Tiles statt einfacher Übergabe relativ kompliziert zugegriffen - <code>dynamic_cast&lt;Game*&gt;(Master::MySurface)-&gt;Tiles</code> (natürlich noch abgekürzt) <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>Dravere schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Was ein Problem darstellt, ist die Tatsache, dass z.B. <code>Player</code> indirekt über die Basisklasse <code>Object</code> auf <code>Game</code> Zugriff haben muss, um z.B. Kollisionsabfragen mit den Tiles zu handhaben.</p>
</blockquote>
<p>Das leuchtet mir überhaupt nicht ein. Wieso kann der Player nicht direkt mit den Tiles interagieren? Game sollte höchstens den Player verschieben oder sowas ähnliches.</p>
</blockquote>
<p>Wie ich schon weiter oben angedeutet habe, hab ich das momentan noch relativ kompliziert (eher global) gelöst. Aber wenn der Spieler direkt mit den Tiles interagieren sollte, müsste ja bei dessen Erstellung im Konstruktor eine Referenz auf die Tiles übergeben werden, und auf Gegner genauso. Gegner wiederum hätten Referenzen auf Spieler und Tiles, was zu Konflikten führt, wenn eines der Objekte noch nicht konstruiert wurde und eine Referenz darauf übergeben wird.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p><code>Game</code> selber benötigt natürlich alle Klassen, die Typen der Member sind.</p>
</blockquote>
<p>Kommt drauf an, wie zentral du Game gestaltest.</p>
</blockquote>
<p>Dravere schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Was wiederum nicht geht, weil im Konstruktor von <code>Game</code> ja auch <code>Player</code> konstruiert wird, und der <code>this</code> -Zeiger von <code>Game</code> zu diesem Zeitpunkt noch auf die Basisklasse <code>Surface</code> verweist... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
</blockquote>
<p>Ah, da haben wir wieder so ein Problem. Du erstellst den Player als Eigenschaft von Game. Aber ist er das wirklich? Ich finde das irgendwie nicht. Einem Game Objekt sollte ein Player Objekt zugewiesen sein, vielleicht auch mehrere, aber es sollte den Player sicher nicht besitzen.<br />
Ein Spieler sollte meiner Meinung nach anderswo erstellt und dem Spiel dann übergeben werden.</p>
</blockquote>
<p>Daran hab ich auch relativ lange überlegt. Ich hab auch eine Klasse <code>Map</code> in Betracht gezogen (für ein Level/eine Karte). Schlussendlich hab ich mich für <code>Game</code> entschieden, weil das so schön zu der Polymorphie mit den <code>Surface</code> s (verschiedene Menüoberflächen) passt (Bei mir ist es so, dass es verschiedene gleichwertige Oberflächen gibt (Hauptmenü, Info, Hilfe, Editor, Game)). Zudem ist es auch logisch sinnvoll, wenn Spieler, Gegner, Tiles gerade erstellt werden, wenn man das Spiel startet (also eine Instanz von <code>Game</code> erstellt). Von mir aus gesehen macht es keinen Sinn, Spieler etc. separat zu erstellen und an <code>Game</code> zu übergeben, weil sie ja unmittelbar daran gebunden sind (welchen Sinn hat ein Spieler ohne Spiel?) <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>Dravere schrieb:</p>
<blockquote>
<p>Auf &quot;The Big Three&quot; verzichtest du, in dem du Zeiger verwendest.</p>
</blockquote>
<p>Ich meinte, ich müsse Copy-Ctor, Dtor und Op= selber implementieren, wenn ich Zeiger als Member habe - was ich bei Stackvariablen nicht muss.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Aber wenn du möglichst Zeiger meiden willst, weil du Angst vor der eigenen Speicherverwaltung hast, dann solltest du vielleicht eine andere Sprache wählen? C# oder Java? Bei C++ sind ja gerade solche Dinge ganz entscheidend und vieles wird darüber aufgebaut. Man verzichtet einfach auf einen ganz entscheidenden Teil der Sprache, wenn man keine eigene Speicherverwaltung einsetzt. Shared Pointer und ähnliches sollten nur Hilfskonstrukte für gewisse Situationen sein, aber nicht für alles.</p>
</blockquote>
<p>Vielleicht hab ich einen falschen Eindruck erweckt, es ist ja nicht so, dass ich ängstlich vor Zeigern und eigener Speicherverwaltung zurückschrecke - ich hab immer noch genügend Orte, wo ich mit <code>new</code> und <code>delete</code> arbeite <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 />
Ich meinte vielmehr, dass eigene Speicherverwaltung halt viele Fehlerrisiken birgt und man viel stärker aufpassen muss. Ich sehe deshalb automatische Speicherverwaltung als &quot;Geschenk&quot; an, das auch eingesetzt werden sollte, wenn es geht (im Übrigen ist es auch noch schneller). Wie Badestrand in seinem Post gesagt hat, würde ich Stackvariablen gegen &quot;praktische&quot; Vorwärtsdeklarationen lieber nicht eintauschen.</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Eine &quot;Master-Option&quot;-Klasse, mache ich höchst selten. Das hat den einfach Grund, dass wenn man die Sache genügend aufsplittet in Objekte und Module, es irgendwann keine Option geben wird, welche für alle oder mehr als die Hälfte gilt. Man sollte zudem, meiner Meinung nach, nicht in solchen Dimensionen denken. Wenn eine Option verändert wird, dann betrifft das direkt entsprechende Objekte und dort sollten die Eigenschaften entsprechend gesetzt werden. Man sollte nicht Optionen zusammenschaufeln und in eine gemeinsame Klasse verfrachten. Ausser das sie Optionen sind, haben diese nämlich nichts gemeinsam!</p>
</blockquote>
<p>Hm... Was meinst du genau mit &quot;Optionen&quot;? Ich hab das Gefühl, wir stellen uns unter einer Masterklasse nicht ganz das Gleiche vor.<br />
Bei mir ist es so, dass nur die ganz zentralen Dinge dort geregelt werden. Der Master ist bezeichnenderweise (sorry, wusste keinen besseren Namen als &quot;Master&quot; :)) die oberste Direktive, die alles regelt. Er überwacht den Verlauf des Programms und gibt den einzelnen Oberflächen (abstrakte Basisklasse <code>Surface</code> ) die Kontrolle, wenn eine entsprechende Eingabe getätigt wurde. Abgesehen von der Kontrollfunktion besitzt er noch einige für Grafikroutinen benötigte Variablen (z.B. das Fenster, oder Event für Eingaben, Schriftarten), dient also auch als Ersatz für globale Variablen.</p>
<p>Aber ganz dezentral kannst du das Programm ja auch nicht steuern (ich nehme nicht an, dass du sehr vieles in der <code>main()</code> -Funktion stehen hast), oder? Ich hab bei mir gerade mal zwei Funktionen in <code>main()</code> , nämlich eine für die Initialisierung und eine für den ständigen Verlauf.</p>
<p>So, wieder viel geschrieben <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="🙂"
    /><br />
Ich hoffe, ihr könnt meine Sichtweise und mein Design einigermassen nachvollziehen - bei irgendwelchen Unklarheiten sofort fragen <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/1565088</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565088</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 14 Aug 2008 23:45:17 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Fri, 15 Aug 2008 10:53:33 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Nein, dann würde es von der Logik her keinen Sinn mehr machen. Ein Tile ist ja ein fester Bestandteil der Welt, d.h. es kann nur rasterförmig ausgerichtet sein (eben in einer Tilemap) und bewegt sich nicht. Objekte wie der Spieler oder abgefeuerte Waffen hingegen sind mobil und reagieren auf Kollision mit der Welt (also den Tiles).</p>
</blockquote>
<p>Das bedeutet für mich eigentlich nur, dass du noch nicht genügend aufgesplittet hast. Dann gibt es eben Kollisionsobjekte und bewegliche Objekte. Ein Player wäre demnach beides, ein Tile nur ein Kollisionsobjekt. Durch die Auftrennung passiert dann auch der Logikfehler nicht mehr.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Ja, also momentan verwalte ich diese Klassen in STL-Containern innerhalb von <code>Game</code> (die eben leer sind falls kein entsprechendes Objekt existiert). Falls es etwas rumzureichen gibt, benutze ich eher Referenzen. Aber das muss ich eh noch ausbauen, jetzt wird z.B. auf die Tiles statt einfacher Übergabe relativ kompliziert zugegriffen - <code>dynamic_cast&lt;Game*&gt;(Master::MySurface)-&gt;Tiles</code> (natürlich noch abgekürzt) <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>
</blockquote>
<p>Das ist nicht nur kompliziert, sondern sogar langsam! Ein dyamic_cast ist teuer, erst recht, wenn er immer wieder ausgeführt wird. Zudem zeigt ein dynamic_cast, wie so oft, darauf hin, dass ein Designfehler vorliegt. Es sollte ohne gehen!<br />
Ein Spieler ist nicht da, um sich zu bewegen, Regeln sind dafür da. Und das Spiel, welches die Tiles beinhaltet und auch den Spieler hat, sollte mit den Regeln den Spieler verschieben. Es kann also alles intern gelöst werden.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Wie ich schon weiter oben angedeutet habe, hab ich das momentan noch relativ kompliziert (eher global) gelöst.</p>
</blockquote>
<p>Ich würde eher sagen, sehr vereinfacht und global gemacht, anstatt genügend differenziert <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>Nexus schrieb:</p>
<blockquote>
<p>Aber wenn der Spieler direkt mit den Tiles interagieren sollte, müsste ja bei dessen Erstellung im Konstruktor eine Referenz auf die Tiles übergeben werden, und auf Gegner genauso.</p>
</blockquote>
<p>Nein. Ich hätte da eher an eine Location gedacht. Also sowas wie:</p>
<pre><code class="language-cpp">class Player
{
  // ...
private:
  Tile* m_location;

  // ...
public:
  void set_location(Tile* location) { m_location = location; };
  Tile* get_location() const { return m_location; };
};
</code></pre>
<p>Wobei man das sicher ausbauen könnte. Vielleicht in das bewegliche Objekt nehmen. Zudem dann überprüfen, ob es eine Kollision gibt oder was auch immer, bzw. ob der Player dort stehen kann. Wenn nicht, muss das Spiel mit den Regeln richtig reagieren und den Spieler anders verschieben. Die Regeln können ja auch als Klassen eingebaut werden. Dann wird einem Regelobjekt der Spieler übergeben und gesagt, er müsse zum Punkt x,y,z gehen. Die Regel probiert das auszuführen und wenn es nicht geht, übergibt sie die Sache anderen Regeln usw.<br />
Hier werden dann auch nur Zeiger durchgereicht oder Referenzen.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Gegner wiederum hätten Referenzen auf Spieler und Tiles, was zu Konflikten führt, wenn eines der Objekte noch nicht konstruiert wurde und eine Referenz darauf übergeben wird.</p>
</blockquote>
<p>Wieso hat der Gegner Referenzen auf Spieler? Und wieso überhaupt Referenzen? Wieso nicht Pointer und dann die Übergabe eines Nullpointers erlauben? Ein Spieler könnte keine Waffe haben, ein Spieler oder Gegner kann nirgends stehen.</p>
<p>Es muss nicht nur das Sinn machen, was der Spieler zu sehen bekommt. Die Funktionsweise eines Spieles sollte mehr können <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>Wieso willst du im übrigen alles mit Referenzen lösen? Referenzen kann man nur ein einziges Mal initialisieren, danach kannst du nie mehr ein anderes Objekt zuweisen. Wenn du deinen Klassen immer nur Referenzen übergibst als Member, dann bindest du sie viel zu stark an die entsprechenden Objekte. Das ist meistens gar nicht nötig. Zudem dürfte es Probleme beim &quot;normalen&quot; Kopieren geben.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Daran hab ich auch relativ lange überlegt. Ich hab auch eine Klasse <code>Map</code> in Betracht gezogen (für ein Level/eine Karte). Schlussendlich hab ich mich für <code>Game</code> entschieden, weil das so schön zu der Polymorphie mit den <code>Surface</code> s (verschiedene Menüoberflächen) passt (Bei mir ist es so, dass es verschiedene gleichwertige Oberflächen gibt (Hauptmenü, Info, Hilfe, Editor, Game)). Zudem ist es auch logisch sinnvoll, wenn Spieler, Gegner, Tiles gerade erstellt werden, wenn man das Spiel startet (also eine Instanz von <code>Game</code> erstellt). Von mir aus gesehen macht es keinen Sinn, Spieler etc. separat zu erstellen und an <code>Game</code> zu übergeben, weil sie ja unmittelbar daran gebunden sind (welchen Sinn hat ein Spieler ohne Spiel?) <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>
</blockquote>
<p>Das der Spieler gerade im Warteraum ist? Bei den Optionen? In den Highscores? Jedenfalls nicht im Spiel.<br />
Zudem sollte man viel eher anschauen, was für Vorteile bringt einem eine entsprechende Kapselung. Sollte wirklich das Spiel den Spieler erstellen? Ich würde eher sagen, das Spiel soll mit dem Spieler interagieren. Erstellen tut sich der Spieler wahrscheinlich selbst, zum Beispiel über ein Profil oder ähnliches. Dann kann er den Namen selber festlegen und die Farbe seiner Spielfigur, oder sowas in der Art <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>Nexus schrieb:</p>
<blockquote>
<p>Ich meinte, ich müsse Copy-Ctor, Dtor und Op= selber implementieren, wenn ich Zeiger als Member habe - was ich bei Stackvariablen nicht muss.</p>
</blockquote>
<p>Also hier liegen irgendwie mehrere Missverständnisse vor:<br />
1. Eine Deep-Copy ist nicht immer nötig. Manchmal will man wirklich nur den Zeiger kopieren und nicht das, worauf der Zeiger zeigt. Siehe es am Beispiel von Player oben. Die Location sollte dort als Zeiger kopiert werden, also eine &quot;flache&quot; Kopie. Man möchte ja auf das gleiche Tile verweisen.<br />
2. Wenn du Zeiger verwendest, dann musst du ja nicht mehr kopieren! Wenn du dem Spiel ein Zeiger auf einen Spieler übergibst, dann soll der Zeiger gespeichert werden und nur der Zeiger weitergegeben werden (oder allenfalls eine Referenz). Der Spieler wird gar nie kopiert, wodurch er keiner der grossen Drei benötigt.<br />
3. Stackvariablen? Bei Stackvariablen brauchst du das je nach dem trotzdem. Und Membervariablen kommen nicht unbedingt auf den Stack! Die kommen dorthin, wo die Klasse erstellt wurde, also womöglich auch auf den Heap. Der Stack ist sowieso begrenzt, man sollte nicht zu viel dort drauf setzen.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Vielleicht hab ich einen falschen Eindruck erweckt, es ist ja nicht so, dass ich ängstlich vor Zeigern und eigener Speicherverwaltung zurückschrecke - ich hab immer noch genügend Orte, wo ich mit <code>new</code> und <code>delete</code> arbeite <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 />
Ich meinte vielmehr, dass eigene Speicherverwaltung halt viele Fehlerrisiken birgt und man viel stärker aufpassen muss. Ich sehe deshalb automatische Speicherverwaltung als &quot;Geschenk&quot; an, das auch eingesetzt werden sollte, wenn es geht ...</p>
</blockquote>
<p>Du hast doch Angst vor den Fehlerrisiken. Aber wenn du sie nie antriffst, dann wirst du immer Angst davor haben. Wenn du automatische Speicherverwaltung als ein &quot;Geschenk&quot; siehst, dann bist du, wie gesagt, in der falschen Sprache. Ich sehe viel eher die nicht automatische Speicherverwaltung als ein wundervolles Geschenk! Sicher, man kann sich damit den ganzen Körper wegsprengen, aber wenn man ein wenig Übung hat, und die sollte man sich aneignen, dann ist das kein Problem mehr.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>... (im Übrigen ist es auch noch schneller). Wie Badestrand in seinem Post gesagt hat, würde ich Stackvariablen gegen &quot;praktische&quot; Vorwärtsdeklarationen lieber nicht eintauschen.</p>
</blockquote>
<p>Stackvariablen können nur temporär erstellt werden oder müssen kopiert werden. Klar bei der Erstellung ist der Stack schneller, wenn du aber danach immer kopieren musst, ist die Übergabe eines Zeigers deutlich schneller, da du auf dem Heap nur ein einziges Mal allokierst.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Hm... Was meinst du genau mit &quot;Optionen&quot;? Ich hab das Gefühl, wir stellen uns unter einer Masterklasse nicht ganz das Gleiche vor.</p>
</blockquote>
<p>Scheint, dass du noch viel mehr darunter verstehst als ich.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Bei mir ist es so, dass nur die ganz zentralen Dinge dort geregelt werden.</p>
</blockquote>
<p>Alles? <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>Nexus schrieb:</p>
<blockquote>
<p>Der Master ist bezeichnenderweise (sorry, wusste keinen besseren Namen als &quot;Master&quot; :)) die oberste Direktive, die alles regelt. Er überwacht den Verlauf des Programms und gibt den einzelnen Oberflächen (abstrakte Basisklasse <code>Surface</code> ) die Kontrolle, wenn eine entsprechende Eingabe getätigt wurde. Abgesehen von der Kontrollfunktion besitzt er noch einige für Grafikroutinen benötigte Variablen (z.B. das Fenster, oder Event für Eingaben, Schriftarten), dient also auch als Ersatz für globale Variablen.</p>
</blockquote>
<p>Eindeutig, alles <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 />
Schon nur das &quot;Ersatz für globale Variablen&quot; zeigt auf, dass da was nicht stimmen kann. Globale Variablen braucht man nicht und man braucht auch kein Ersatz dafür. Deshalb ist das Singleton-Pattern auch so umstritten, weil es oft als Ersatz für globale Variablen herangezogen wird, was es nicht sein sollte.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Aber ganz dezentral kannst du das Programm ja auch nicht steuern (ich nehme nicht an, dass du sehr vieles in der <code>main()</code> -Funktion stehen hast), oder? Ich hab bei mir gerade mal zwei Funktionen in <code>main()</code> , nämlich eine für die Initialisierung und eine für den ständigen Verlauf.</p>
</blockquote>
<p>Ich habe normalerweise kaum etwas in der Main, weil ich eben dezentral programmiere. Wenn ich viel in die Main schreiben würde, dann würde diese zu einem zentralen Punkt werden, nicht?</p>
<p>Aber man kann dezentral programmieren, man muss nur genügend aufsplitten. Gerade deine Master und Game Klassen sind für mich eindeutige Hinweise darauf, dass du noch nicht genügend gesplittet hast.</p>
<p>Aber mal ein wenig allgemeiner und ich bitte dich, die Frage nicht böse zu verstehen. Wieviel hast du in C++ schon gemacht? Und wieviel hast du schon zu C++ gelesen, welche Bücher? Versteh mich bitte nicht falsch, aber ich habe ein wenig das Gefühl, dass ein Spiel zu programmieren, vielleicht eine Stufe zu hoch ist.</p>
<p>So, das war nun wirklich ein riesiger Post. Ich könnte noch mehr schreiben, muss aber essen gehen und möchte auch noch selber heute was programmieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1565324</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565324</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Fri, 15 Aug 2008 10:53:33 GMT</pubDate></item><item><title><![CDATA[Reply to Kompilierzeitprobleme mit modularer Programmierung on Fri, 15 Aug 2008 13:50:46 GMT]]></title><description><![CDATA[<blockquote>
<p>Versteh mich bitte nicht falsch, aber ich habe ein wenig das Gefühl, dass ein Spiel zu programmieren, vielleicht eine Stufe zu hoch ist.</p>
</blockquote>
<p>So, wie ich Nexus einschätze, reicht sein können für ein einfaches Spiel allemale. Sein Problem ist hald, wie ich vermute, dass er sich im vornherein zu viele Gedanken macht.<br />
Imhos sollte er einfach mal anfangen und dann wird er früher, oder später merken, was an dem Design Mist ist. Das prägt sich dann auch mehr ein und man kennt Alternativen. (Weil es hier vlt. schlecht war, heisst ja nicht, dass es wo anderst nicht mal von Nutzen sein kann).</p>
<blockquote>
<p>Hast du demnach auch das Problem mit langen Kompilierzeiten? Oder sind deine Projekte einfach so riesig?</p>
</blockquote>
<p>Es ist mittlerweile Recht gross geworden. (Die grösse .cpp hat ca. 1500 Zeilen. ) <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>Um da jetzt mal den Vergleich zu machen. Dort ist mein gesamtes GUI System drin. Und das habe ich imho schon recht gut gemacht, aber ich sage dir, wenn ich, dass ich am liebsten alles nochmal neu schreiben würde, weil so richtig gefällt mir das ganze eigl. nicht. Aber ich habe auch keine Lust das ganze nochmal zu machen, vor allem, da ich dann wahrscheinlich auch nicht 100% zufrieden bin. <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="😉"
    /> - Ich denke mal, dass es da vielen gleich geht. Man ist irgendwie nie richtig zufriede mit dem, was man hat. <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/1565494</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1565494</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Fri, 15 Aug 2008 13:50:46 GMT</pubDate></item></channel></rss>