<?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[Highscore-Klasse]]></title><description><![CDATA[<p>Hallo zusammen.<br />
Schreibe gerade an einer Klasse zur Verwaltung eines Highscore-Systems in einem Spiel. Die Klasse soll möglichst unabhängig sein, so dass sie in mehreren Spielen verwendet werden kann.<br />
Ich möchte hier schon einmal einen ersten Entwurf des Klassendesigns zeigen, um Rückmeldungen diesbezüglich zu erhalten. So kann ich schnell Fehler oder Probleme erkennen und Verbesserungen einfließen lassen.</p>
<p>Also die Klasse soll eine Liste verwalten, welche die Highscore repräsentiert.<br />
Mit den nötigen Zugriffsoperationen wird diese Liste dann verändert und das Dateihandling vorgenommen.<br />
Hier mein erster Entwurf (bestimmt noch nicht vollständig, aber ein erster Anfang):</p>
<pre><code class="language-cpp">#ifndef CHighscore_h
#define CHighscore_h

#include &lt;list&gt;

struct HighscoreEntry
{
	char name[30];
	int punkte;	
};

class CHighscore
{
	public:
		CHighscore(); //liest Liste aus Datei ein
		virtual ~CHighscore(); //schreibt Liste wieder in Datei

		//Die Liste nach &quot;außen&quot; hin geben (-&gt; Ausgabe o.ä.)
		void getHighscoreList(std::list&lt;HighscoreEntry&gt; &amp;pList);

		//neuen Eintrag in die Liste einfügen
		void AddnewEntry(HighscoreEntry pNew);

	protected:
		std::list&lt;HighscoreEntry&gt; mHighscoreList;		
};

#endif //CHighscore_h
</code></pre>
<p>Ich denke, die Kommentare sind ausreichend und erklären gut, wie ich mit die Aufgabenverteilung in den einzelnen Funktionen vorgestellt habe.</p>
<p>Ich hoffe auf Anmerkungen und Kritik (oder auch Zustimmung ;)).</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/220630/highscore-klasse</link><generator>RSS for Node</generator><lastBuildDate>Tue, 06 Oct 2026 14:09:16 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/220630.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 18 Aug 2008 21:33:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 21:33:18 GMT]]></title><description><![CDATA[<p>Hallo zusammen.<br />
Schreibe gerade an einer Klasse zur Verwaltung eines Highscore-Systems in einem Spiel. Die Klasse soll möglichst unabhängig sein, so dass sie in mehreren Spielen verwendet werden kann.<br />
Ich möchte hier schon einmal einen ersten Entwurf des Klassendesigns zeigen, um Rückmeldungen diesbezüglich zu erhalten. So kann ich schnell Fehler oder Probleme erkennen und Verbesserungen einfließen lassen.</p>
<p>Also die Klasse soll eine Liste verwalten, welche die Highscore repräsentiert.<br />
Mit den nötigen Zugriffsoperationen wird diese Liste dann verändert und das Dateihandling vorgenommen.<br />
Hier mein erster Entwurf (bestimmt noch nicht vollständig, aber ein erster Anfang):</p>
<pre><code class="language-cpp">#ifndef CHighscore_h
#define CHighscore_h

#include &lt;list&gt;

struct HighscoreEntry
{
	char name[30];
	int punkte;	
};

class CHighscore
{
	public:
		CHighscore(); //liest Liste aus Datei ein
		virtual ~CHighscore(); //schreibt Liste wieder in Datei

		//Die Liste nach &quot;außen&quot; hin geben (-&gt; Ausgabe o.ä.)
		void getHighscoreList(std::list&lt;HighscoreEntry&gt; &amp;pList);

		//neuen Eintrag in die Liste einfügen
		void AddnewEntry(HighscoreEntry pNew);

	protected:
		std::list&lt;HighscoreEntry&gt; mHighscoreList;		
};

#endif //CHighscore_h
</code></pre>
<p>Ich denke, die Kommentare sind ausreichend und erklären gut, wie ich mit die Aufgabenverteilung in den einzelnen Funktionen vorgestellt habe.</p>
<p>Ich hoffe auf Anmerkungen und Kritik (oder auch Zustimmung ;)).</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567223</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567223</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Mon, 18 Aug 2008 21:33:18 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 21:59:14 GMT]]></title><description><![CDATA[<ol>
<li>
<p>Woher weiß der Construktor denn welche Datei er öffnen muss?</p>
</li>
<li>
<p>Ich würde GetHighscoreList eher so machen:</p>
</li>
</ol>
<pre><code class="language-cpp">std::list&lt;HighscoreEntry&gt;&amp; getHighscoreList( void );
// oder, je nachdem wie du es haben willst
const std::list&lt;HighscoreEntry&gt;&amp; getHighscoreList( void ) const;
</code></pre>
<p>Damit kann man besser arbeiten.</p>
<ol start="3">
<li>Bei AddNewEntry kannst du den Parameter auch als Referenz übergeben.</li>
</ol>
<pre><code class="language-cpp">void AddnewEntry( const HighscoreEntry&amp; pNew);
</code></pre>
<ol start="4">
<li>
<p>Wofür steht das p vor deinen Variablen?</p>
</li>
<li>
<p>Verwende lieber std::string anstatt char[]</p>
</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/1567236</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567236</guid><dc:creator><![CDATA[Fusel.Factor]]></dc:creator><pubDate>Mon, 18 Aug 2008 21:59:14 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 22:38:08 GMT]]></title><description><![CDATA[<p>Fusel.Factor schrieb:</p>
<blockquote>
<pre><code class="language-cpp">std::list&lt;HighscoreEntry&gt;&amp; getHighscoreList( void );
// oder, je nachdem wie du es haben willst
const std::list&lt;HighscoreEntry&gt;&amp; getHighscoreList( void ) const;
</code></pre>
</blockquote>
<p>Das halte ich für ziemlich ziemlich schlecht. Im Prinzip hat die Idee was, aber einer der Vorteile von Kapselung ist ja, dass man die dahinter-liegende Implementation auswechseln kann, ohne dass der &quot;Benutzer&quot; der Klasse was davon mitbekommt oder sogar seinen Code ändern muss. Wenn du nun eine Referenz zurückgibst, kannst du später nicht mehr die std::list durch z.B. einen std::vector oder ein std::set ersetzen, da du dann keine list-Referenz mehr hast.<br />
Wenn du hingegen ein Objekt statt einer Referenz zurückgibst, kannst du intern ruhig die Liste durch einen vector ersetzen, die Schnittstelle funktioniert trotzdem noch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567250</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567250</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Mon, 18 Aug 2008 22:38:08 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 22:57:30 GMT]]></title><description><![CDATA[<p>Zu den bereits gesagten Dingen möchte ich noch einige Vorschläge hinzufügen:</p>
<ul>
<li>Für eine Highscore würde ich nicht <code>std::list</code> , sondern <code>std::set</code> bzw. <code>std::multiset</code> verwenden. Du musst dann den Operator &lt; (als Default; hängt vom Sortierkriteriums-Funktor ab) für deine Eintragsklasse überladen, dafür werden die Einträge automatisch sortiert.</li>
<li>Das Struct würde ich innerhalb der Klasse, und zwar im privaten Bereich definieren. Es werden ja keine Einträge ausserhalb der Highscore benötigt.</li>
<li>Hast du deine Klasse zur Ableitung vorgesehen? Ansonsten sind <code>virtual</code> und <code>protected</code> unpassend.</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/1567255</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567255</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 18 Aug 2008 22:57:30 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 23:03:14 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13210">@Badestrand</a>: So ganz überzeugend ist das in meinen Augen nicht. Immerhin wirkt sich die Rückgabe eines neuen Containers negativ auf die Laufzeitkomplexität aus, auch nimmt man dann unnötig die Möglichkeit von Exceptions in Kauf. Wenn die Implementation wirklich so instabil ist, sollte vielleicht eher die Verwendung eines Proxies oder Views in Erwägung gezogen werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567256</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567256</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 18 Aug 2008 23:03:14 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 23:00:45 GMT]]></title><description><![CDATA[<p>Badestrand schrieb:</p>
<blockquote>
<p>Das halte ich für ziemlich ziemlich schlecht. Im Prinzip hat die Idee was, aber einer der Vorteile von Kapselung ist ja, dass man die dahinter-liegende Implementation auswechseln kann, ohne dass der &quot;Benutzer&quot; der Klasse was davon mitbekommt oder sogar seinen Code ändern muss. Wenn du nun eine Referenz zurückgibst, kannst du später nicht mehr die std::list durch z.B. einen std::vector oder ein std::set ersetzen, da du dann keine list-Referenz mehr hast.<br />
Wenn du hingegen ein Objekt statt einer Referenz zurückgibst, kannst du intern ruhig die Liste durch einen vector ersetzen, die Schnittstelle funktioniert trotzdem noch.</p>
</blockquote>
<p>Das ist zwar wahr, aber da gibt es eine Zwischenlösung:</p>
<pre><code class="language-cpp">class Foo
{
  // Typedefs //
public:
  typedef std::list&lt;Entry&gt; Container_t;

  // Attributes //
private:
  Container_t m_container;

  // Methods //
public:
  Container_t&amp; get_container() { return m_container; };
  Container_t const&amp; get_container() const { return m_container; };
};
</code></pre>
<p>So kann man <code>std::list</code> zum Beispiel durch einen <code>std::vector</code> oder ein <code>std::set</code> ersetzen. Eine Zwischenlösung ist es deswegen, weil man die Sache nicht zum Beispiel durch <code>eine std::map</code> ersetzen kann.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567257</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567257</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 18 Aug 2008 23:00:45 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Mon, 18 Aug 2008 23:40:25 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a>: Ich finde, bei Klassen wo die Laufzeit so ziemlich egal ist (wie hier, wenn nicht sehr viele Einträge drin sind), kann man ruhig Objekte zurückgeben. Zudem dürfte eine Get-Highscore-Funktion ja nicht in einem aufwendigen Algorithmus zum Tragen kommen, so dass sie (in meinen Augen) eigentlich nie ein Flaschenhals sein kann.<br />
Die Gefahr von Exceptions sehe ich hier auch nicht, immerhin haben wir die Kontrolle des Container-Templ.-Parameters und es kommen nur ziemlich simple Typen zum Einsatz.<br />
Wenn man aber generell Objekte zurückgibt (wie ich das immer mache), stimmen die Argumente natürlich voll und ganz!</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>: Warum dann nicht gleich einen öffentlichen Container_t-Member, nimmt sich dann ja nichts mehr?</p>
<p>Ich weiß auch nicht, aber ich hab wirklich eine grundsätzliche Abneigung gegen Referenz-Rückgabe <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> Klar ist die Objekt-Rückgabe wesentlich langsamer, aber das entreißt mir irgendwie zu stark die Kontrolle; ist vielleicht ein Tick von mir oder so <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/1567262</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567262</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Mon, 18 Aug 2008 23:40:25 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 00:56:05 GMT]]></title><description><![CDATA[<p>Badestrand schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>: Warum dann nicht gleich einen öffentlichen Container_t-Member, nimmt sich dann ja nichts mehr?</p>
</blockquote>
<p>Naja, ich muss zugeben, bei meinen Klassen biete ich normalerweise nur diese Methode an:</p>
<pre><code class="language-cpp">Container_t const&amp; get_container() const { return m_container; };
</code></pre>
<p>Und das einfach aus dem Grund, da es so praktisch ist, alle Einträge zu durchlaufen. Egal in welche Richtung und ich nicht alle Methoden vom Container wrappen muss.</p>
<p>Wenn ich die völlig offene Methode anbiete:</p>
<pre><code class="language-cpp">Container_t&amp; get_container() { return m_container; }
</code></pre>
<p>Dann kommt natürlich sowieso die andere dazu. Viel wichtiger ist aber, dass ich dann keine spezielle Kontrolle über die Liste haben will. Es ist also alles erlaubt mit der Liste zu machen. Sonst müsste ich alle Funktionen wrappen und dazu habe ich keine Lust.</p>
<p>In dem Fall der Klasse hier, würde ich übrigens vorschlagen, dass man sie vollständig entfernt. Die Klasse <code>CHighscore</code> ist wahrscheinlich nur ein Wrapper für ein <code>std::multiset</code> . Daher wäre es klüger die Klasse <code>HighscoreEntry</code> auszubauen und wie es bereits Nexus vorgeschlagen hat, mit einem <code>operator &lt;</code> auszustatten.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567268</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567268</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 19 Aug 2008 00:56:05 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 07:27:08 GMT]]></title><description><![CDATA[<p>So, erstmal Danke für die große Anzahl an Rückmeldungen.</p>
<p>Die Absicht der Klasse war, sie völlig unabhängig von anderem Code in den Spielen zu schreiben, eben so, dass intern in der Klasse alles verwaltet wird.<br />
Daher würde ich auch lieber eine Klasse nehmen, welche die komplette Verwaltung der Highscore übernimmt.<br />
Von außen soll man dann nur Objekte eingeben und die Ausgabe der Highscore zurückkriegen können. Mehr sollte ich ja eigentlich nicht brauchen.</p>
<p>Um die Sortierung der Liste muss ich mir eingentlich keine Gedanken machen, da neue Objekte sortiert eingefügt werden und so die Liste immer sortiert ist.</p>
<p>Über die Abhängigkeit von std::list denke ich nochmal nach, obwohl ich finde, dass eine Liste völlig ausreichend ist, da diese einfach zu durchlaufen ist und auch immer sortiert vorliegt. Werde aber gucken, ob ich mir offen halte, den Container noch zu ändern...</p>
<p>Ist die Variante, dass der Konstruktor die Liste aus der Datei läd und der Destruktor die Liste wieder in die Datei schreibt, so gut?<br />
So gehe ich sicher, dass diese Operationen auf jeden Fall durchgeführt werden, was sie ja auch müssen.</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567322</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567322</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Tue, 19 Aug 2008 07:27:08 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 07:40:48 GMT]]></title><description><![CDATA[<p>Eine Möglichkeit die Scores manuell zu speichern ist sicherlich auch sinnvoll. Gerade dann wenn das Spiel auch gerne noch mal anfangs crasht und der Destruktor nicht aufgerufen wird.</p>
<p>Ansonsten würde ich eine Templateklasse draus machen.</p>
<p>Und zwar sollte der Name vom Typ std::string sein und der eigentliche Highscorewert der Templateparameter. So funktioniert es dann mit int, float... Vielleicht noch ein Datum dazu? Als Timestamp.</p>
<p>So kannst du auch dann die get-Methode gestalten:</p>
<pre><code class="language-cpp">bool getEntry(int num, std::string &amp;name, T &amp;value, unsigned int &amp;timestamp){
  if (list.size() &lt;= num) return false;

  name = ...
  value = ... 
  timestamp = ...

  return true;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1567325</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567325</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Tue, 19 Aug 2008 07:40:48 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 07:48:36 GMT]]></title><description><![CDATA[<p>Fellhuhn schrieb:</p>
<blockquote>
<p>Eine Möglichkeit die Scores manuell zu speichern ist sicherlich auch sinnvoll. Gerade dann wenn das Spiel auch gerne noch mal anfangs crasht und der Destruktor nicht aufgerufen wird.</p>
</blockquote>
<p>Die Spiele selber sind soweit fertig, sie sollten eigentlich nicht mehr abstürzen, der Highscore ist nun nur eine kleine Erweiterung der Spiele..<br />
Denke also, ich lasse es erstmal im Destruktor. Wäre natürlich auch keine große Sache, das in eine Methode zu packen, die ich dann munuell aufrufe.</p>
<p>Fellhuhn schrieb:</p>
<blockquote>
<p>Ansonsten würde ich eine Templateklasse draus machen.</p>
<p>Und zwar sollte der Name vom Typ std::string sein und der eigentliche Highscorewert der Templateparameter. So funktioniert es dann mit int, float... Vielleicht noch ein Datum dazu? Als Timestamp.</p>
<p>So kannst du auch dann die get-Methode gestalten:</p>
<pre><code class="language-cpp">bool getEntry(int num, std::string &amp;name, T &amp;value, unsigned int &amp;timestamp){
  if (list.size() &lt;= num) return false;

  name = ...
  value = ... 
  timestamp = ...

  return true;
}
</code></pre>
</blockquote>
<p>Das mit dem Template werde ich mal versuchen, so bin ich natürlich noch unabhängiger. Das mit dem Datum ist auch eine gute Idee, das werde ich wohl mit aufnehmen..</p>
<p>Was meint ihr? Brauche ich denn jetzt noch mehr als das Hinzufügen neuer Einträge und die Ausgabe der Highscore?<br />
Diese beiden Funktionen werde ich auf jeden Fall schon mal möglicht komfortabel und unabhängig implementieren.</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567331</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567331</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Tue, 19 Aug 2008 07:48:36 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 14:57:53 GMT]]></title><description><![CDATA[<p>Hundefutter schrieb:</p>
<blockquote>
<p>Um die Sortierung der Liste muss ich mir eingentlich keine Gedanken machen, da neue Objekte sortiert eingefügt werden und so die Liste immer sortiert ist.<br />
[...]<br />
Über die Abhängigkeit von std::list denke ich nochmal nach, obwohl ich finde, dass eine Liste völlig ausreichend ist, da diese einfach zu durchlaufen ist und auch immer sortiert vorliegt.</p>
</blockquote>
<p>Da verwechselst du was. <code>std::list</code> ist eine doppelt verkettete Liste, also ein sequenzieller und kein assoziativer Container. Da wird auch nichts automatisch sortiert, sonst wären wohl Methoden wie <code>push_front()</code> und <code>push_back()</code> relativ sinnlos. Wie gesagt, nimm für einen automatisch sortierten Container ein <code>std::set</code> oder <code>std::multiset</code> , wenn mehrere identische Schlüssel vorkommen dürfen. Da kann man auch die maximale Anzahl Werte überwachen:</p>
<pre><code class="language-cpp">while (set_container.size() &gt; 5)
    set_container.erase(set_container.begin());
</code></pre>
<p>Hundefutter schrieb:</p>
<blockquote>
<p>Was meint ihr? Brauche ich denn jetzt noch mehr als das Hinzufügen neuer Einträge und die Ausgabe der Highscore?<br />
Diese beiden Funktionen werde ich auf jeden Fall schon mal möglicht komfortabel und unabhängig implementieren.</p>
</blockquote>
<p>Vielleicht noch eine Funktion zum Zurücksetzen der Highscore.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567668</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567668</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 19 Aug 2008 14:57:53 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 15:09:25 GMT]]></title><description><![CDATA[<p>Warum fängt die Methode getHighscore mit einem kleinen g an und die Methode AddnewEntry mit einem großen a? Und warum ist das n bei new klein? &quot;addnew&quot; ist kein englisches Wort, das sind zwei Wörter, also sollte es AddNew sein.</p>
<p>Ich vote übrigens für addNewEntry statt GetHighscore <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>Außerdem würde ich etwas mehr Arbeit investieren und nicht einfach die Datenstruktur in der die Highscores gespeichert werden zurückgeben, sondern die einzelnen Einträge bzw. einen Iterator mit dem man diese durchgehen kann.<br />
Außerdem würde ich einen op&lt;&lt; und op&gt;&gt; hinzufügen um die Highscore bequem speichern und laden zu können <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 />
Ebenso einen Konstruktor der einen std::istream entgegen nimmt und aus diesem die Highscore lädt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567676</guid><dc:creator><![CDATA[S.T.A.L.K.E.R.]]></dc:creator><pubDate>Tue, 19 Aug 2008 15:09:25 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 16:13:00 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Da verwechselst du was. <code>std::list</code> ist eine doppelt verkettete Liste, also ein sequenzieller und kein assoziativer Container. Da wird auch nichts automatisch sortiert, sonst wären wohl Methoden wie <code>push_front()</code> und <code>push_back()</code> relativ sinnlos.</p>
</blockquote>
<p>Mir ist klar, dass die Liste nicht automatisch sortiert wird, nur da ich den neuen Eintrag immer sofort sortiert einfüge, liegt sie immer sortiert vor und sie nie unsortiert, also muss auch nichts sortiert werden.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Vielleicht noch eine Funktion zum Zurücksetzen der Highscore.</p>
</blockquote>
<p>Jo, das könnte noch mit aufgenommen werden.</p>
<p>S.T.A.L.K.E.R. schrieb:</p>
<blockquote>
<p>Außerdem würde ich etwas mehr Arbeit investieren und nicht einfach die Datenstruktur in der die Highscores gespeichert werden zurückgeben, sondern die einzelnen Einträge bzw. einen Iterator mit dem man diese durchgehen kann.<br />
Außerdem würde ich einen op&lt;&lt; und op&gt;&gt; hinzufügen um die Highscore bequem speichern und laden zu können <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 />
Ebenso einen Konstruktor der einen std::istream entgegen nimmt und aus diesem die Highscore lädt.</p>
</blockquote>
<p>Jo, werde ich auch versuchen mit zu implementieren.</p>
<p>Mache mich gleich mal dran, weiter an der Klasse zu arbeiten.<br />
Schreibe dann später wieder die aktuelle Version.</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567728</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567728</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Tue, 19 Aug 2008 16:13:00 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 16:28:12 GMT]]></title><description><![CDATA[<p>Darf ich ein zwei Vorschläge anbringen?</p>
<pre><code class="language-cpp">class HighscoreEntry
{
private:
  std::string m_name;
  long m_timestamp;
  long m_points;

public:
  HighscoreEntry(std::string const&amp; name, long points, long timestamp)
    : m_name(name)
    , m_points(points)
    , m_timestamp(timestamp)
  { }

  ~HighscoreEntry() { };

public:
  std::string const&amp; get_name() const { return m_name; };
  void set_name(std::string const&amp; name) { m_name = name; };

  long get_timestamp() const { return m_timestamp; };
  void set_timestamp(long timestamp) { m_timestamp = timestamp; };

  long get_points() const { return m_points; };
  void set_points(long points) { m_points = points; };
};

inline bool operator &lt;(HighscoreEntry const&amp; left, HighscoreEntry const&amp; right)
{
  return (left.get_points() == right.get_points() ?
           left.get_name().compare(right.get_name()) &lt; 0 :
           left.get_points() &lt; right.get_points());
}

typedef std::multiset&lt;HighscoreEntry&gt; Highscore_t;

inline void write_highscore(std::string const&amp; path, Highscore_t const&amp; highscore)
{
  /* Schreibfunktion */
}

inline void read_highscores(std::string const&amp; path, Highscore_t&amp; highscore)
{
  highscore.clear();

  /* ... lese die Highscore ... */
}
</code></pre>
<p>Wäre meiner Meinung nach am einfachsten, nicht?<br />
<code>std::multiset</code> übernimmt auch die Sortierung deiner Einträge voll automatisch und sortiert sie schneller ein, als deine <code>std::list</code> das kann. Denn du musst die Liste sequentiell durchlaufen, um den Eintrag zu platzieren.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567742</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567742</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 19 Aug 2008 16:28:12 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Tue, 19 Aug 2008 20:14:17 GMT]]></title><description><![CDATA[<p>Hui, das ist ja schon fast eine komplette Lösung..<br />
Danke für deine Mühe.<br />
Finde die Lösungsart sehr gut und werde es nun selbst versuchen ähnlich zu implementieren. Ich merke selbst, dass mir noch sehr viel Übung fehlt, gerade im Umgang mit der STL..<br />
Also versuche ich das Ganze erstmal selbst, kann mir ja dann deine Lösung hier angucken, falls ich nicht weiterkomme.</p>
<p>Vielen Dank an alle für die Hilfen.</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1567856</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1567856</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Tue, 19 Aug 2008 20:14:17 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Sun, 24 Aug 2008 13:37:37 GMT]]></title><description><![CDATA[<p>Ich habe jetzt für mich so eine Klasse geschrieben, deren Objekte Einträge der Highscore sind.<br />
Nun habe ich versucht, mit multiset zu arbeiten, nur irgendwie läuft bei mir der insert-Befehl nicht.</p>
<pre><code class="language-cpp">std::multiset&lt;HighscoreEntry&gt; Highscore; //multiset vom Typ HighscoreEntry
std::multiset&lt;HighscoreEntry&gt;::iterator it; //entsprechender Iterator

std::string name;
int points;

std::cout &lt;&lt; &quot;Name: &quot;;
std::cin &gt;&gt;  name;
std::cout &lt;&lt; &quot;Punkte: &quot;;
std::cin &gt;&gt; points;

HighscoreEntry Entry(name, points); //Instanz der Klasse

Highscore.insert(Entry); //Zeile, die den Fehler verursacht
</code></pre>
<p>Beim Kompilieren meckert er (siehe unten).<br />
Kann es sein, dass der Vergleichstyp hier noch nicht definiert ist? Der Container muss ja nach einem bestimmten Kriterium sortiert werden und ich denke mir, er weiß bei dem Typ nicht, wie er es machen soll...</p>
<p>Hier die Fehlerausgabe:</p>
<blockquote>
<p>make -k all<br />
Building file: ../main.cpp<br />
Invoking: GCC C++ Compiler<br />
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF&quot;main.d&quot; -MT&quot;main.d&quot; -o&quot;main.o&quot; &quot;../main.cpp&quot;<br />
/usr/include/c++/4.1.3/bits/stl_function.h: In member function »bool std::less&lt;_Tp&gt;::operator()(const _Tp&amp;, const _Tp&amp;) const [with _Tp = HighscoreEntry]«:<br />
/usr/include/c++/4.1.3/bits/stl_tree.h:857: instantiated from »typename std::_Rb_tree&lt;_Key, _Val, _KeyOfValue, _Compare, _Alloc&gt;::iterator std::_Rb_tree&lt;_Key, _Val, _KeyOfValue, _Compare, _Alloc&gt;::insert_equal(const _Val&amp;) [with _Key = HighscoreEntry, _Val = HighscoreEntry, _KeyOfValue = std::_Identity&lt;HighscoreEntry&gt;, _Compare = std::less&lt;HighscoreEntry&gt;, _Alloc = std::allocator&lt;HighscoreEntry&gt;]«<br />
/usr/include/c++/4.1.3/bits/stl_multiset.h:310: instantiated from »typename std::_Rb_tree&lt;_Key, _Key, std::_Identity&lt;_Key&gt;, _Compare, typename _Alloc::rebind&lt;_Key&gt;::other&gt;::const_iterator std::multiset&lt;_Key, _Compare, _Alloc&gt;::insert(const _Key&amp;) [with _Key = HighscoreEntry, _Compare = std::less&lt;HighscoreEntry&gt;, _Alloc = std::allocator&lt;HighscoreEntry&gt;]«<br />
../main.cpp:20: instantiated from here<br />
/usr/include/c++/4.1.3/bits/stl_function.h:227: Fehler: no match für »operator&lt;« in »__x &lt; __y«<br />
make: *** [main.o] Fehler 1<br />
make: Das Target »all« wurde wegen Fehlern nicht aktualisiert.<br />
Build complete for project Highscore-Klasse</p>
</blockquote>
<p>Was meint ihr dazu? Wo liegt hier noch der Fehler?</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1570485</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1570485</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Sun, 24 Aug 2008 13:37:37 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Sun, 24 Aug 2008 13:47:38 GMT]]></title><description><![CDATA[<p>Steht ja in der Fehlermeldung, obwohl die wirklich sehr mühsam sind, die GCC-Fehlermeldungen:</p>
<blockquote>
<p>Fehler: no match für »operator&lt;« in »__x &lt; __y«</p>
</blockquote>
<p>Also der <code>operator &lt;</code> fehlt für die Klasse <code>HighscoreEntry</code> . Du musst also einen entsprechenden <code>operator &lt;</code> definieren. Ein Beispiel dafür siehst du in meinem Beispiel oben <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>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1570492</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1570492</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sun, 24 Aug 2008 13:47:38 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Sun, 24 Aug 2008 14:34:30 GMT]]></title><description><![CDATA[<p>Ich habe nun mal versucht, deine Definition des Operators einzufügen:</p>
<pre><code class="language-cpp">inline bool operator &lt;(HighscoreEntry const &amp;left, HighscoreEntry const &amp;right);
</code></pre>
<p>Nun sagt er mir aber immer, dass die Funktion nur ein Element nehmen darf:</p>
<pre><code>../HighscoreEntry.h:18: Fehler: »bool HighscoreEntry::operator&lt;(const HighscoreEntry&amp;, const HighscoreEntry&amp;)« muss genau ein Argument nehmen
</code></pre>
<p>Warum sagt der das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1570523</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1570523</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Sun, 24 Aug 2008 14:34:30 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Sun, 24 Aug 2008 14:43:23 GMT]]></title><description><![CDATA[<p>Ich habe den <code>operator &lt;</code> ausserhalb der Klasse definiert, wie man es bei diesen Operatoren oft macht. Du dagegen, hast den <code>operator &lt;</code> in der Klasse definiert. Wenn du ihn in der Klasse definierst, dann hast du als erster Wert <code>this</code> , also das eigentliche Objekt und als zweiter Wert, den übergebenen wert. Wenn du noch einen zweiten Parameter definierst, hättest du eigentlich 3 Werte zum vergleichen, was mit dem <code>operator &lt;</code> nicht geht. deshalb die Fehlermeldung.</p>
<p>Also entweder raus aus der Klasse damit oder wenn du ihn in der Klasse behälst, dann einen Parameter weniger und mit <code>this</code> vergleichen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1570528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1570528</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sun, 24 Aug 2008 14:43:23 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Sun, 24 Aug 2008 14:53:27 GMT]]></title><description><![CDATA[<p>Ach klar, dummer Fehler... <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>Naja, dann ist ja alles klar.</p>
<p>Danke für die Hinweise.</p>
<p>MfG<br />
Hundefutter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1570535</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1570535</guid><dc:creator><![CDATA[Hundefutter]]></dc:creator><pubDate>Sun, 24 Aug 2008 14:53:27 GMT</pubDate></item><item><title><![CDATA[Reply to Highscore-Klasse on Sun, 24 Aug 2008 15:13:04 GMT]]></title><description><![CDATA[<p>Also das hier ist schon mal blödsinn</p>
<p>bool getEntry(int num, std::string &amp;name, T &amp;value, unsigned int &amp;timestamp){<br />
if (list.size() &lt;= num) return false;</p>
<p>name = ...<br />
value = ...<br />
timestamp = ...</p>
<p>return true;<br />
}</p>
<p>das muss so aussehne</p>
<p>string getEntry(int num, std::string &amp;name, T &amp;value, unsigned int &amp;timestamp){<br />
if (list.length() &lt;= num) return true;</p>
<p>name = ...<br />
value = ...<br />
timestamp = ...</p>
<p>return 0;<br />
}</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1570541</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1570541</guid><dc:creator><![CDATA[1337HacKeR]]></dc:creator><pubDate>Sun, 24 Aug 2008 15:13:04 GMT</pubDate></item></channel></rss>