<?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[Objekte als Parameter und in multimaps]]></title><description><![CDATA[<p>Ich mache mir gerade Gedanken über die Darstellung eines Spielfelds für ein Computerspiel, und bin zu dem Schluss gekommen, daß die Multimap aus der STL wohl am geeignetsten wäre.</p>
<p>Konkret würde ich gern von einem Coordinate-Objekt (also nur x- und y-Position) auf Spielfeldobjekte abbilden (weil bei meinem Spiel auf einem Feld mehrere Sachen stehen können).</p>
<p>Jetzt habe ich aber an zwei Stellen das Problem, daß es mehrere unterschiedliche Objekte sein können, die ich in diese Multimap an einer Koordinate packen will, d.h. einerseits ist meine Frage ob ich in eine add_item Funktion mit einem generischen Objekt Parameter deklarieren kann, also z.b.</p>
<p>add_item(Object new_Object, int x_pos, int y_pos)</p>
<p>bzw. wie ich das sonst machen kann (mir würde da sonst nur das Überladen der add-item Funktion für jedes mögliche Objekt einzeln einfallen),</p>
<p>und andererseits kommt natürlich die Frage auf, wie ich die multimap deklarieren muss, also ob es sowas wie</p>
<p>multimap&lt;Coordinate, Object&gt;</p>
<p>gibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/194479/objekte-als-parameter-und-in-multimaps</link><generator>RSS for Node</generator><lastBuildDate>Tue, 29 Sep 2026 23:20:35 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/194479.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 07 Oct 2007 15:31:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Sun, 07 Oct 2007 15:31:38 GMT]]></title><description><![CDATA[<p>Ich mache mir gerade Gedanken über die Darstellung eines Spielfelds für ein Computerspiel, und bin zu dem Schluss gekommen, daß die Multimap aus der STL wohl am geeignetsten wäre.</p>
<p>Konkret würde ich gern von einem Coordinate-Objekt (also nur x- und y-Position) auf Spielfeldobjekte abbilden (weil bei meinem Spiel auf einem Feld mehrere Sachen stehen können).</p>
<p>Jetzt habe ich aber an zwei Stellen das Problem, daß es mehrere unterschiedliche Objekte sein können, die ich in diese Multimap an einer Koordinate packen will, d.h. einerseits ist meine Frage ob ich in eine add_item Funktion mit einem generischen Objekt Parameter deklarieren kann, also z.b.</p>
<p>add_item(Object new_Object, int x_pos, int y_pos)</p>
<p>bzw. wie ich das sonst machen kann (mir würde da sonst nur das Überladen der add-item Funktion für jedes mögliche Objekt einzeln einfallen),</p>
<p>und andererseits kommt natürlich die Frage auf, wie ich die multimap deklarieren muss, also ob es sowas wie</p>
<p>multimap&lt;Coordinate, Object&gt;</p>
<p>gibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1379785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1379785</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Sun, 07 Oct 2007 15:31:38 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Sun, 07 Oct 2007 16:22:44 GMT]]></title><description><![CDATA[<p>Wenn du die beiden Objekttypen von einer gemeinsamen Basisklasse (am besten abstrakt) erben läßt, dann kannst du diese Objekte in die Multimap stecken. Nachteil dabei ist, daß du immer mit Zeigern arbeiten mußt, d.h. die Objekte müssen mit new allokiert werden anstatt als Kopie in die Multimap gesteckt werden.</p>
<pre><code class="language-cpp">class Base
{
};

class A : public Base
{
};

class B : public Base
{
};

class Coordinate
{
  Coordinate(int x, int y);
};

typedef std::multimap&lt; Coordinate, Base* &gt; Map;
typedef Map::value_type MapType;

mmap.insert(MapType(Coordinate(1,2), new A()));
mmap.insert(MapType(Coordinate(1,2), new B()));
mmap.insert(MapType(Coordinate(2,4), new B()));
</code></pre>
<p>Beim Löschen eines Objektes aus der Multimap mußt du dann aber noch das eigentliche Objekt von Hand deleten (am besten du schreibst dir dafür dann eine eigene Funktion).</p>
<p>Ich hoffe du kennst dich mit Vererbung und virtuellen Methoden aus, ansonsten stöbere mal ein bißchen danach.</p>
<p>Edit: Klammerfehler beseitigt</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1379827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1379827</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Sun, 07 Oct 2007 16:22:44 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Sun, 07 Oct 2007 19:32:23 GMT]]></title><description><![CDATA[<p>Erstmal danke für die Antwort, das ist das, wonach ich suche.</p>
<p>Ich habe aber noch drei Fragen, denn erstens wüsste ich gern, was folgende Zeile in deinem Code machen soll:</p>
<pre><code class="language-cpp">typedef Map::value_type MapType;
</code></pre>
<p>Edit: Habs selber rausgefunden..</p>
<p>Dann habe ich noch das Problem, daß ich nicht verstehe, was ich machen soll, wenn ich ein Objekt auf einen anderen Key &quot;umkopieren&quot; will.<br />
Muss ich mir dazu das Objekt aus der Multimap holen und dann an der neuen Stelle ein neues Objekt (also mit den Werten des alten) mit new() anlegen?</p>
<p>Und schlussendlich, kannst du das mit dem deleten wenigstens etwas genauer erklären? In C++ kann man ein Objekt ja über einen Destruktor oder über delete() löschen, was davon muss ich in diesem Fall nehmen?</p>
<p>Leider sind meine C++ Fähigkeiten ein wenig begrenzt, und Lektüre über Vererbung und virtuelle Methoden hat mir keine Erleuchtung bei dieser Frage gebracht.</p>
<p>Achja und nochwas:<br />
Sind Hash-Multimaps besser?<br />
Und wenn ja, sind die in der STL drin und können ohne weiteres benutzt werden? In der Doku zur STL stand was davon, daß die immernoch nicht im C++ Standart drin sind und man selber eine Hashfunktion schreiben müsste, was für mich als Anfänger dann doch eher schlecht wäre...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1379991</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1379991</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Sun, 07 Oct 2007 19:32:23 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Sun, 07 Oct 2007 20:49:05 GMT]]></title><description><![CDATA[<p>Hi</p>
<p>zu 1.<br />
Hast du ja anscheinend jetzt verstanden:<br />
der Typedef dient nur dazu, nicht so viel tippen zu müssen...</p>
<p>zu 2.<br />
Wenn du ein Objekt kopieren willst, dann mußt du das neue Objekt wieder mit new erzeugen (am besten dafür dann einen Copy-Konstruktor verwenden).<br />
Wenn du ein Objekt einfach an eine andere Koordinate verschieben willst, dann brauchst du das Objekt nicht nochmal neu erzeugen (da es ja schon existiert).<br />
Du mußt es nur an der alten Koordinate löschen (s. 3) und an der neuen Koordinate einfügen.</p>
<p>zu 3.<br />
wenn ein Objekt mit 'new'erzeugt wurde, muß es auch irgendwo wieder mit 'delete' gelöscht werden (dieser ruft dann implizit den Destruktor der Klasse auf).<br />
Wenn du ein Objekt aus der Multimap komplett löschen willst, dann mußt du es nicht nur aus der Multimap löschen (da dort nur der Zeiger vorhanden ist), sondern auch noch das eigentliche Objekt deleten.<br />
Beispiel:</p>
<pre><code class="language-cpp">Map::iterator it = ...; // Iterator auf das zu löschende Element
delete *it;
map.erase(it);
</code></pre>
<p>Um an die Elemente einer Multimap zu kommen, schau dir mal die Methoden lower_range, upper_range und equal_range an.</p>
<p>zu 4. (obwohl du ja eigentlich nur 3 Fragen hattest, aber erste hast du ja selbst beantwortet)<br />
Je nach STL-Implementierung gibt es auch Hash-(Multi)Maps, aber diese brauchst du erst zu verwenden, wenn die Performance der normalen Multimaps zu gering ist (d.h. wenn du einige Tausend oder mehr Objekte hast).<br />
Im kommenden C++ Standard soll es dann sogenannte &quot;unordered maps&quot; geben, welche den Hash-Maps entsprechen.</p>
<p>Evtl. gibt es aber noch bessere Datentypen für dein Problem als die Multimap.<br />
Wenn das Spielbrett eine geringe Zahl an Positionen hat, würde ich eher ein Array (vector) verwenden und je Position eine Liste von Objekten:</p>
<pre><code class="language-cpp">std::list&lt;Base*&gt; fields[MaxX][MaxY]; // alternativ auch std::vector
</code></pre>
<p>So ich hoffe, das hilft dir weiter...<br />
Ich gehe jetzt ins Bett und evtl. schaue ich morgen noch mal hier rein -)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380093</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380093</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Sun, 07 Oct 2007 20:49:05 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 09:46:25 GMT]]></title><description><![CDATA[<p>Wow, also ersteinmal abermals vielen Dank, ich werde mich direkt mal dran setzen, das zu implementieren.</p>
<p>Deine Idee mit Array/Vector/Liste hatte ich auch schon, aber mein Spielfeld(ich mache ein Weltraum-Strategiespiel) hat definitiv viel zu viele Felder (ich mag es bei solchen Spielen, wenn der Maßstab riesig ist), als daß ich mir ein Array oder Vector leisten wollte. Ausserdem sind ja die meisten Felder eh leerer Weltraum, deswegen finde ich ne Multimap schon recht angemessen.</p>
<p>Oder irre ich mich da? Wie gesagt, ich bin leider noch recht &quot;wackelig&quot; im Programmiergeschäft, und wenn du meinst, es gibt eine effizientere Methode, dann werd ich die sicher ausprobieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380317</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380317</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 09:46:25 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 10:03:06 GMT]]></title><description><![CDATA[<p>Wenn die Mehrheit deiner Felder leer ist, waere es wirklich nur Platzverschwendung, wenn du mit einem array/vector arbeitest, weil du dann ja fuer jedes einen leeren Eintrag (z.B null-pointer) anlegen muesstest.<br />
Alternativ zur Multimap kannst du auch eine normale Map von Listen verwenden, das waere dann der Mittelweg zwischen Multimap und dem vector&lt;list&lt;base*&gt; &gt;-Ansatz.<br />
Je nachdem bietet es sich evtl. auch an, die Objekte die sich an den entsprechenden Punkten befinden koennen als Komposita zu gestalten, so dass du mehrere davon zusammenfassen und das zusammengefasste Objekt an Stelle der list in die normale map packen kannst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380331</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380331</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 08 Oct 2007 10:03:06 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 13:15:08 GMT]]></title><description><![CDATA[<p>Also, ich habe jetzt mal versucht, den Vorschlag von Pumuckl zu implementieren, da ich *gehofft* habe, daß es mit den Lists in ner Map einfacher ist als mit ner Multimap.</p>
<p>Hier der Code so far:</p>
<pre><code class="language-cpp">#ifndef GALAXYMAP_HPP
#define GALAXYMAP_HPP

#include &quot;Stellarobject.hpp&quot;
#include &quot;Starsystem.hpp&quot;
#include &quot;Coordinate.hpp&quot;

#include &lt;map&gt;
#include &lt;list&gt;

class Galaxymap
{
	public:
		void add_item(Starsystem new_starsystem, int new_x_pos, int new_y_pos);
		void remove_item(Stellarobject curr_object, int x_pos, int y_pos);

	private:

		int x_size;
		int y_size;

		typedef map&lt;Coordinate, list&lt;Stellarobject*&gt; &gt; Galaxy_map;
		typedef Galaxy_map::value_type map_ype; 
};
#endif
</code></pre>
<pre><code class="language-cpp">#include &quot;Galaxymap.hpp&quot;

void Galaxymap::add_item(Starsystem cur_starsystem, int new_x_pos, int new_y_pos)
{
	//empty field in map?
	if(Galaxy_map.find(Coordinate(new_x_pos,new_y_pos)) == Galaxy_map.end())
	{
		//yes, so a new list has to be created and the new item has to be put in it
		list&lt;Stellarobject*&gt; new_list;
		new_list.push_back(new Starsystem(cur_starsystem));
		Galaxy_map.insert(map_type(Coordinate(new_x_pos,new_y_pos), new list&lt;Stellarobject*&gt;(new_list)));
	}
	else
	{
		//no, the item just has to be put into the existing list
		list&lt;Stellarobject*&gt; existing_list = Galaxy_map.find(Coordinate(new_x_pos, new_y_pos));
		existing_list.push_back(new Starsystem(cur_starsystem));
		Galaxy_map.insert(map_type(Coordinate(new_x_pos,new_y_pos), new list&lt;Stellarobject*&gt;(existing_list)));
	}
}

void Galaxymap::remove_item(Stellarobject curr_object, int x_pos, int y_pos)
{
	//Is there a list at the coordinates?
	if(Galaxy_map.get(Coordinate(x_pos,y_pos)) == NULL)
	{
		//No, there is no list which means that there is nothing at all
		cout &lt;&lt; &quot;Failed to find object at position&quot; &lt;&lt; x_pos &lt;&lt; &quot; &quot; &lt;&lt; y_pos &lt;&lt; &quot;(Map empty)&quot; &lt;&lt; endl;
	}
	else
	{
		//There is a list, so we have to search it for the object
		list&lt;Stellarobject*&gt; temp_list = Galaxy_map.get(Coordinate(x_pos, y_pos));

		list&lt;Stellarobject*&gt;:: iterator it;

		bool delete_success = false;

		for (it = temp_list.begin(); it != temp_list.end(); ++it)
		{
			if(it == curr_object)
			{
				delete *it;
				temp_list.erase(it);
				delete_success = true;
			}
		}
		if(!delete_success)
		{
			cout &lt;&lt; &quot;Object wasn´t in the list&quot; &lt;&lt; endl;
		}
	}
}
</code></pre>
<p>Dazu habe ich jetzt wieder einige Fragen:</p>
<p>1. Mein Compiler meint dazu:</p>
<blockquote>
<p>Galaxymap.cpp:6: error: expected primary-expression before '.' token</p>
</blockquote>
<p>und bezieht sich immerwieder damit auf Galaxy_map. Ist da was mit der typedef schiefgelaufen?<br />
Passend dazu kommt noch:</p>
<blockquote>
<p>Galaxymap.cpp:11: error: `map_type' undeclared (first use this function)</p>
</blockquote>
<p>Und dann würde ich gern wissen, wie ich das hier richtig schreiben muss, weil es nur so ne Art placeholder ist, damit ihr versteht, was das mal werden soll</p>
<pre><code class="language-cpp">if(it == curr_object)
</code></pre>
<p>Ich will damit erreichen, daß das if ausgeführt wird wenn der iterator auf dem objekt steht, das ich suche...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380477</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380477</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 13:15:08 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 13:54:46 GMT]]></title><description><![CDATA[<p>Ich werd mal deinen ganzen text quoten und Stueckweise meinen Senf dazu abgeben <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>Sceletor schrieb:</p>
<blockquote>
<p>[cpp]<br />
#ifndef GALAXYMAP_HPP<br />
#define GALAXYMAP_HPP</p>
<p>#include &quot;Stellarobject.hpp&quot;<br />
#include &quot;Starsystem.hpp&quot;<br />
#include &quot;Coordinate.hpp&quot;</p>
<p>#include &lt;map&gt;<br />
#include &lt;list&gt;</p>
<p>class Galaxymap<br />
{<br />
public:<br />
void add_item(Starsystem new_starsystem, int new_x_pos, int new_y_pos);<br />
void remove_item(Stellarobject curr_object, int x_pos, int y_pos);</p>
</blockquote>
<p>Wenn du Zeiger auf Stellarobject in deinen Listen speicherst, sollte add_item evtl auch einen Zeiger oder eine Referenz auf ein solches uebernehmen, sonst musst du spaeter noch ein add_item(star_ship, int, int) und ein add_item(asteroid, int, int) usw. dazuschreiben. Ich wuerde einen Zeiger empfehlen, da sich der Aufrufer ja selbst um die Speicherverwaltung kuemmern muss und eine uebergabe per Referenz meist impliziert, dass das Objekt kopiert wird und der Container die Speicherverwaltung uebernimmt.<br />
Bei remove_item reciht auch eine Referenz oder ein Zeiger, es ist unnoetig da das Objekt zu kopieren (die Kopie querde in den meisten Faellen auch den Vergleihcsoperator fuer die Suche fehlschlagen lassen)</p>
<blockquote>
<p>private:</p>
<p>int x_size;<br />
int y_size;</p>
<p>typedef map&lt;Coordinate, list&lt;Stellarobject*&gt; &gt; Galaxy_map;<br />
typedef Galaxy_map::value_type map_ype; //TIPPFEHLER!!!<br />
};<br />
#endif<br />
[/cpp]</p>
<pre><code class="language-cpp">#include &quot;Galaxymap.hpp&quot;

void Galaxymap::add_item(Starsystem cur_starsystem, int new_x_pos, int new_y_pos)
{
	//empty field in map?
	if(Galaxy_map.find(Coordinate(new_x_pos,new_y_pos)) == Galaxy_map.end())
	{
		//yes, so a new list has to be created and the new item has to be put in it
		list&lt;Stellarobject*&gt; new_list;
		new_list.push_back(new Starsystem(cur_starsystem));
</code></pre>
</blockquote>
<p>Wenn du hier tatsaechlich selbst die Speicherverwaltung in die Hand nehmen willst, ok... aber dann reicht immernoch eine Referenz als parameter, und du musst den ganzen Mist fuer andere stellarobjects nochmal schreiben (evtl. template)</p>
<blockquote>
<pre><code class="language-cpp">Galaxy_map.insert(map_type(Coordinate(new_x_pos,new_y_pos), new list&lt;Stellarobject*&gt;(new_list)));
</code></pre>
</blockquote>
<p>statt map_type geht auch atd::make_pair(), und da du eine map&lt;Coordinate, list&gt; hast, sollte da hinten kein new stehen.</p>
<blockquote>
<pre><code class="language-cpp">}
	else
	{
		//no, the item just has to be put into the existing list
		list&lt;Stellarobject*&gt; existing_list = Galaxy_map.find(Coordinate(new_x_pos, new_y_pos));
		existing_list.push_back(new Starsystem(cur_starsystem));
</code></pre>
</blockquote>
<p>STOP! Du kopierst hier die Liste die du in deiner Map gefunden hast und packst das Neue Objekt in die Kopie, die nach der Funktion wieder geloescht wird. =&gt; Referenz auf die gefundene Liste benutzen.</p>
<blockquote>
<pre><code class="language-cpp">Galaxy_map.insert(map_type(Coordinate(new_x_pos,new_y_pos), new list&lt;Stellarobject*&gt;(existing_list)));
</code></pre>
</blockquote>
<p>letzteres kann dann wegfallen. Du versuchst hier naemlich eine Liste einzufuegen an eine Stelle, wo schon etwas war, das Einfuegen schlaegt daher fehl.</p>
<blockquote>
<pre><code class="language-cpp">}
}

void Galaxymap::remove_item(Stellarobject curr_object, int x_pos, int y_pos)
{
	//Is there a list at the coordinates?
	if(Galaxy_map.get(Coordinate(x_pos,y_pos)) == NULL)
</code></pre>
</blockquote>
<p>Das funktioniert so nicht. Wenn an den Koordinaten nix ist, gibts auch keine Liste. Ausserdem handelst du mit einer map&lt;Coordinate, List&gt; und nicht mit einer map von pointern. Versuchs mit</p>
<pre><code class="language-cpp">/*iterator*/ pos = Galaxy_map.find(Coordinate();
if (pos == Galaxy_map.end()) //...
</code></pre>
<p>im else-Zweig dann ueber den iterator weiterarbeiten</p>
<blockquote>
<pre><code class="language-cpp">{
		//No, there is no list which means that there is nothing at all
		cout &lt;&lt; &quot;Failed to find object at position&quot; &lt;&lt; x_pos &lt;&lt; &quot; &quot; &lt;&lt; y_pos &lt;&lt; &quot;(Map empty)&quot; &lt;&lt; endl;
	}
	else
	{
		//There is a list, so we have to search it for the object
		list&lt;Stellarobject*&gt; temp_list = Galaxy_map.get(Coordinate(x_pos, y_pos));
</code></pre>
</blockquote>
<p>ueber den iterator von vorhin einfach auf die Liste zugreifen udn nicht unnoetig kopieren.</p>
<blockquote>
<pre><code class="language-cpp">list&lt;Stellarobject*&gt;:: iterator it;

		bool delete_success = false;

		for (it = temp_list.begin(); it != temp_list.end(); ++it)
		{
			if(it == curr_object)
			{
				delete *it;
				temp_list.erase(it);
				delete_success = true;
			}
		}
</code></pre>
</blockquote>
<p>versuchs mal mit std::find, das liefert dir auch gleich den list::iterator, fuer den du dann erase() aufrufen kannst</p>
<blockquote>
<pre><code class="language-cpp">if(!delete_success)
		{
			cout &lt;&lt; &quot;Object wasn´t in the list&quot; &lt;&lt; endl;
		}
	}
}
</code></pre>
<p>Dazu habe ich jetzt wieder einige Fragen:</p>
<p>1. Mein Compiler meint dazu:</p>
<blockquote>
<p>Galaxymap.cpp:6: error: expected primary-expression before '.' token</p>
</blockquote>
</blockquote>
<p>Welches ist Zeile 6 bei dir?</p>
<blockquote>
<p>und bezieht sich immerwieder damit auf Galaxy_map. Ist da was mit der typedef schiefgelaufen?<br />
Passend dazu kommt noch:</p>
<blockquote>
<p>Galaxymap.cpp:11: error: `map_type' undeclared (first use this function)</p>
</blockquote>
</blockquote>
<p>Da hast du n tippfehler in der typedef</p>
<blockquote>
<p>Und dann würde ich gern wissen, wie ich das hier richtig schreiben muss, weil es nur so ne Art placeholder ist, damit ihr versteht, was das mal werden soll</p>
<pre><code class="language-cpp">if(it == curr_object)
</code></pre>
</blockquote>
<p>siehe oben, std::find() nutzen. Das liefert dann list.end() zurueck, wenn das gesuchte objekt nicht in der liste ist</p>
<blockquote>
<p>Ich will damit erreichen, daß das if ausgeführt wird wenn der iterator auf dem objekt steht, das ich suche...</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1380509</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380509</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 08 Oct 2007 13:54:46 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 15:04:05 GMT]]></title><description><![CDATA[<p>Sceletor, du hast mit der Zeile 'typedef ...' nur eine Typen-Definition erzeugst, aber noch keine Variable.</p>
<pre><code class="language-cpp">typedef std::map&lt;Coordinate, list&lt;Stellarobject*&gt; &gt; Galaxy_map;
typedef Galaxy_map::value_type map_type;

Galaxy_map m_map; // &lt;- Variable, d.h. diese mußt du in deinen Sourcen angeben!
};
</code></pre>
<p>Die typedefs benutzt man extra, damit man nicht immer explizit die komplette template-Definition hinschreiben muß (z.B. bei Iteratoren), d.h.</p>
<pre><code class="language-cpp">Galaxy_map::iterator it = m_map.find(...);
</code></pre>
<p>ist kürzer und eleganter als</p>
<pre><code class="language-cpp">std::map&lt;Coordinate, list&lt;Stellarobject*&gt; &gt;::iterator = m_map.find(...);
</code></pre>
<p>P.S. Ich habe in die Definition extra noch den Namensraum 'std' hinzugefügt, da alle C++ Standard Typen dort enthalten sind. (deswegen kommen evtl. deine Compiler-Fehler)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380563</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380563</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Mon, 08 Oct 2007 15:04:05 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 15:29:08 GMT]]></title><description><![CDATA[<p>Ah, hatte mich gefragt, ob das typedef die deklaration übernimmt, aber mich dann zu blind auf deinen Code verlasse, Th..</p>
<p>Ich habe jetzt mal versucht, die Änderungen von Pumuckel einzuarbeiten, aber ich hänge (den Compilermeldungen nach zu urteilen) immernoch bei den Deklarationen der Listen mit den Pointern.</p>
<p>Da es wohl kaum Sinn mach, alles schnipselweise zu posten (am Ende lass ich was wichtiges aus) hier nochmal der gesamte Code.</p>
<pre><code class="language-cpp">#ifndef GALAXYMAP_HPP
#define GALAXYMAP_HPP

#include &quot;Stellarobject.hpp&quot;
#include &quot;Starsystem.hpp&quot;
#include &quot;Coordinate.hpp&quot;

#include &lt;map&gt;
#include &lt;list&gt;

class Galaxymap
{
	public:
		void add_item(Stellarobject *new_stellar, int new_x_pos, int new_y_pos);
		void remove_item(Stellarobject *curr_stellar, int x_pos, int y_pos);

	private:

		int x_size;
		int y_size;

		typedef std::map&lt;Coordinate, list&lt;Stellarobject*&gt; &gt; Galaxy_map;
		typedef Galaxy_map::value_type map_type;
		Galaxy_map Curr_map;
};
#endif
</code></pre>
<pre><code class="language-cpp">#include &quot;Galaxymap.hpp&quot;

void Galaxymap::add_item(Stellarobject *new_stellar, int new_x_pos, int new_y_pos)
{
	//empty field in map?
	if(Curr_map.find(Coordinate(new_x_pos,new_y_pos)) == Curr_map.end())
	{
		//yes, so a new list has to be created and the new item has to be put in it
		list&lt;Stellarobject*&gt; new_list;
		new_list.push_back(new_stellar);
		Curr_map.insert(map_type(Coordinate(new_x_pos,new_y_pos), list&lt;Stellarobject*&gt;(new_list)));
	}
	else
	{
		//no, the item just has to be put into the existing list
		list&lt;Stellarobject*&gt; existing_list = Curr_map.find(Coordinate(new_x_pos, new_y_pos));
		existing_list.push_back(new_stellar);
	}
}

void Galaxymap::remove_item(Stellarobject *curr_stellar, int x_pos, int y_pos)
{
	//Is there a list at the coordinates?
	list&lt;Stellarobject*&gt;::iterator it = Curr_map.find(Coordinate(x_pos,y_pos));

	if(it = Curr_map.end())
	{
		//No, there is no list which means that there is nothing at all
		cout &lt;&lt; &quot;Failed to find object at position&quot; &lt;&lt; x_pos &lt;&lt; &quot; &quot; &lt;&lt; y_pos &lt;&lt; &quot;(Map empty)&quot; &lt;&lt; endl;
	}
	else
	{
		//There is a list, so we have to search it for the object
		list&lt;Stellarobject*&gt; temp_list = it;

		list&lt;Stellarobject*&gt;::iterator new_it;

		new_it = temp_list.find(curr_stellar);
		if(new_it == temp_list.end())
		{
		cout &lt;&lt; &quot;Object wasn´t in the list&quot; &lt;&lt; endl;
		}
		else
		{
			delete *new_it;
			temp_list.erase(new_it);
		}
	}
}
</code></pre>
<p>Und das sagt der Compiler dazu:</p>
<blockquote>
<p>Galaxymap.cpp: In member function <code>void Galaxymap::add_item(Stellarobject*, int, int)': Galaxymap.cpp:16: error: conversion from \</code>std::_Rb_tree_iterator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;' to non-scalar type `std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;' requested<br />
Galaxymap.cpp: In member function <code>void Galaxymap::remove_item(Stellarobject*, int, int)': Galaxymap.cpp:26: error: could not convert</code>((<em>&amp;it) &lt;unknown operator&gt; ((const std::_Rb_tree_iterator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject</em>, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;&amp;)((const std::_Rb_tree_iterator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;<em>)(&amp;(((std::map&lt;Coordinate, std::list&lt;Stellarobject</em>, std::allocator&lt;Stellarobject*&gt; &gt;, std::less&lt;Coordinate&gt;, std::allocator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt; &gt;<em>)((Galaxymap</em>)this)) + 8u)-&gt;std::map&lt;_Key, _Tp, _Compare, _Alloc&gt;::end [with _Key = Coordinate, _Tp = std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;, _Compare = std::less&lt;Coordinate&gt;, _Alloc = std::allocator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;]()))))' to <code>bool' Galaxymap.cpp:34: error: conversion from \</code>std::_Rb_tree_iterator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;' to non-scalar type `std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;' requested<br />
Galaxymap.cpp:38: error: 'class std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;' has no member named 'find'<br />
Galaxymap.cpp:39: error: no match for 'operator==' in 'new_it == (&amp;temp_list)-&gt;std::list&lt;_Tp, _Alloc&gt;::end [with _Tp = Stellarobject*, _Alloc = std::allocator&lt;Stellarobject*&gt;]()'<br />
C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_tree.h:209: note: candidates are: bool std::_Rb_tree_iterator&lt;_Tp&gt;::operator==(const std::_Rb_tree_iterator&lt;_Tp&gt;&amp;) const [with _Tp = std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt;]<br />
Galaxymap.cpp:45: error: type `struct std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt;' argument given to `delete', expected pointer<br />
Galaxymap.cpp:46: error: no matching function for call to <code>std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;::erase(std::\_Rb\_tree_iterator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;&amp;)' C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/list.tcc:96: note: candidates are: typename std::list&lt;\_Tp, \_Alloc&gt;::iterator std::list&lt;\_Tp, \_Alloc&gt;::erase(std::\_List\_iterator&lt;\_Tp&gt;) \[with \_Tp = Stellarobject*, _Alloc = std::allocator&lt;Stellarobject*&gt;\] C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl\_list.h:894: note: std::\_List\_iterator&lt;\_Tp&gt; std::list&lt;\_Tp, \_Alloc&gt;::erase(std::\_List\_iterator&lt;\_Tp&gt;, std::\_List\_iterator&lt;\_Tp&gt;) \[with \_Tp = Stellarobject*, \_Alloc = std::allocator&lt;Stellarobject*&gt;\] C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl\_function.h: In member function</code>bool std::less&lt;_Tp&gt;::operator()(const _Tp&amp;, const _Tp&amp;) const [with _Tp = Coordinate]':<br />
C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_tree.h:1102: instantiated from <code>typename std::\_Rb\_tree&lt;\_Key, \_Val, \_KeyOfValue, \_Compare, \_Alloc&gt;::iterator std::\_Rb\_tree&lt;\_Key, \_Val, \_KeyOfValue, \_Compare, \_Alloc&gt;::find(const \_Key&amp;) \[with \_Key = Coordinate, \_Val = std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt;, \_KeyOfValue = std::\_Select1st&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;, \_Compare = std::less&lt;Coordinate&gt;, \_Alloc = std::allocator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;\]' C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl\_map.h:498: instantiated from</code>typename std::_Rb_tree&lt;_Key, std::pair&lt;const _Key, _Tp&gt;, std::_Select1st&lt;std::pair&lt;const _Key, _Tp&gt; &gt;, _Compare, _Alloc&gt;::iterator std::map&lt;_Key, _Tp, _Compare, _Alloc&gt;::find(const _Key&amp;) [with _Key = Coordinate, _Tp = std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;, _Compare = std::less&lt;Coordinate&gt;, _Alloc = std::allocator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;]'<br />
Galaxymap.cpp:6: instantiated from here<br />
C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_function.h:227: error: no match for 'operator&lt;' in '__x &lt; __y'</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1380580</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380580</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 15:29:08 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 15:58:31 GMT]]></title><description><![CDATA[<p>Wie ich schon sagte, liegen alle C++ Standard Typen im Namensraum 'std'.</p>
<p>Am besten du erzeugst dir für jede Typ-Definition ein eigenes typedef:</p>
<pre><code class="language-cpp">typedef std::list&lt;Stellarobject*&gt; ObjectList; // sorry, hier hatte ich auch erst std:: vergessen (war natürlich nur ein Test, ob du es kapiert hast -)

typedef std::map&lt;Coordinate, ObjectList &gt; Galaxy_map;
</code></pre>
<p>Nun kannst du einfach</p>
<pre><code class="language-cpp">ObjectList new_list;
</code></pre>
<p>schreiben.</p>
<p>Die restlichen Fehler muß du dann Zeile für Zeile durchgehen (oftmals werden dann Folgefehler angezeigt, die dann bei Eliminierung der ersten Fehler verschwinden).</p>
<p>Aber nur durch die Fehler versteht man C++ richtig (auch wenn die Fehlerbeschreibungen nicht gerade einfach sind - insbesondere bei den komplexen template-Definitionen).</p>
<p>P.S. sorry, hatte bei meinem ersten Posting die Variablen-Deklaration 'Map mmap' vergessen -)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380597</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Mon, 08 Oct 2007 15:58:31 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 17:30:50 GMT]]></title><description><![CDATA[<p>Okay, ich bin meinen Code nochmal in Ruhe durchgegangen und habe ein paar Fehler gefunden.</p>
<p>Was ich aber immernoch nicht verstehe, ist wie ich aus meiner Map nun die Liste bzw. aus der Liste das konkrete Objekt extrahiere.<br />
Mit find() erhalte ich ja nur einen Iterator, der auf den Key zeigt, an dem die Liste ist, oder einen Iterator, der auf das Ende der Map zeigt, wenn der Key nicht drin ist.</p>
<p>Aber wie hole ich mit einem Iterator nun die Liste oder besser nen Zeiger auf die Liste?</p>
<p>Das hier funktioniert einfach nicht, aber was ist daran falsch?</p>
<pre><code class="language-cpp">Galaxy_map::iterator it = Curr_map.find(Coordinate(new_x_pos, new_y_pos));
		Stellar_list existing_list = it;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1380691</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380691</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 17:30:50 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 18:28:59 GMT]]></title><description><![CDATA[<p>Iteratoren kann man im Grunde wie Zeiger verwenden (* und -&gt; Operator)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380729</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380729</guid><dc:creator><![CDATA[The-Kenny]]></dc:creator><pubDate>Mon, 08 Oct 2007 18:28:59 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 19:26:49 GMT]]></title><description><![CDATA[<p>Könntest du das bitte etwas ausführen, d.h. mir sagen wie das in meinem konkreten Fall anzuwenden wäre?</p>
<p>Folgendes</p>
<pre><code class="language-cpp">Stellar_list existing_list = *it;
</code></pre>
<p>habe ich schon vor einer Weile ausprobiert, und ich bekomme damit immernoch die Fehlermeldung</p>
<pre><code>Galaxymap.cpp:17: error: conversion from `std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt;' to 
non-scalar type `std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;' requested
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1380776</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380776</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 19:26:49 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 19:29:37 GMT]]></title><description><![CDATA[<p>AAAARGL</p>
<p>Ich habs....</p>
<pre><code class="language-cpp">Stellar_list existing_list = it-&gt;second;
</code></pre>
<p>Man muss natürlich aus dem Paar (Key,Value) den Value aussuchen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380778</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380778</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 19:29:37 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 19:40:00 GMT]]></title><description><![CDATA[<p>Doch noch ne Frage:</p>
<p>pumuckl schrieb:</p>
<blockquote>
<pre><code class="language-cpp">list&lt;Stellarobject*&gt;:: iterator it;

		bool delete_success = false;

		for (it = temp_list.begin(); it != temp_list.end(); ++it)
		{
			if(it == curr_object)
			{
				delete *it;
				temp_list.erase(it);
				delete_success = true;
			}
		}
</code></pre>
<p>versuchs mal mit std::find, das liefert dir auch gleich den list::iterator, fuer den du dann erase() aufrufen kannst</p>
</blockquote>
<p>Ist das nicht falsch? Nach der Beschreibung der STL hat doch nur die map eine find() Funktion, nicht aber die List, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380785</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 19:40:00 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 19:50:35 GMT]]></title><description><![CDATA[<p>Er redet wohl von std::find, einer Funktion aus dem Header &lt;algorythm&gt;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380794</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380794</guid><dc:creator><![CDATA[The-Kenny]]></dc:creator><pubDate>Mon, 08 Oct 2007 19:50:35 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Mon, 08 Oct 2007 21:15:54 GMT]]></title><description><![CDATA[<p>Ah, okay, hab ich gerade auch eingebaut, und der Compiler ist zufrieden damit.</p>
<p>Was mich aber immernoch verwundert, sind folgende Fehlermeldungen:</p>
<blockquote>
<p>C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_function.h: In member function <code>bool std::less&lt;\_Tp&gt;::operator()(const \_Tp&amp;, const \_Tp&amp;) const \[with _Tp = Coordinate\]': C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl\_tree.h:1102: instantiated from</code>typename std::_Rb_tree&lt;_Key, _Val, _KeyOfValue, _Compare, _Alloc&gt;::iterator std::_Rb_tree&lt;_Key, _Val, _KeyOfValue, _Compare, _Alloc&gt;::find(const _Key&amp;) [with _Key = Coordinate, _Val = std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt;, _KeyOfValue = std::_Select1st&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;, _Compare = std::less&lt;Coordinate&gt;, _Alloc = std::allocator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;]'<br />
C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_map.h:498: instantiated from `typename std::_Rb_tree&lt;_Key, std::pair&lt;const _Key, _Tp&gt;, std::_Select1st&lt;std::pair&lt;const _Key, _Tp&gt; &gt;, _Compare, _Alloc&gt;::iterator std::map&lt;_Key, _Tp, _Compare, _Alloc&gt;::find(const _Key&amp;) [with _Key = Coordinate, _Tp = std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt;, _Compare = std::less&lt;Coordinate&gt;, _Alloc = std::allocator&lt;std::pair&lt;const Coordinate, std::list&lt;Stellarobject*, std::allocator&lt;Stellarobject*&gt; &gt; &gt; &gt;]'<br />
Galaxymap.cpp:6: instantiated from here<br />
C:/Dev-Cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_function.h:227: error: no match for 'operator&lt;' in '__x &lt; __y'</p>
</blockquote>
<p>Hier Zeile 6 der Galaxymap.cpp:</p>
<pre><code>if(Curr_map.find(Coordinate(new_x_pos,new_y_pos)) == Curr_map.end())
</code></pre>
<p>Was bitte will mir der Compiler mit dem Salat sagen??</p>
<p>EDIT:</p>
<p>Habe hier im Forum was gefunden, bei nem Thread, wo jemand fast dasselbe vorhatte wie ich und auch denselben Fehler bekam. Als Lösung wurde folgendes gepostet:</p>
<p>.filmor schrieb:</p>
<blockquote>
<p>Maps werden immer nach ihrem Schlüsseltyp sortiert. Damit das funktioniert, brauchst du ein Vergleichskriterium.<br />
Standardmäßig ist der Comparetyp std::less&lt;KeyType&gt; und std::less ist mit dem &lt;-Operator definiert.<br />
Du hast also 3 Möglichkeiten, den Code zum Laufen zu bringen:<br />
1. Du schreibst einen &lt;-Operator für MyClass (ist aber nur sinnvoll, wenn ein solcher Vergleich tatsächlich logisch möglich ist)<br />
2. Du spezialisierst das std::less-Template für deine Klasse<br />
3. Du schreibst eine eigene Vergleichsfunktion (das Sinnvollste, wenn du nur in einem Kontext eine solche Map anlegst.</p>
</blockquote>
<p>Mein Problem ist, daß ich leider keine der drei möglichen Lösungen nachvollziehen kann und auch nicht weiss, welche davon nun für mich die einfachste/effektivste wäre.</p>
<p>Ich glaube zu verstehen, daß es darum geht, der STL beizubringen, wie sie meine Koordinaten nach Größe sortieren kann. Da wäre ja logisch einfach (entweder X oder Y Wert höher gewichten), aber wie und vor allem wo muss ich das implementieren.<br />
Wäre für Codebeispiele sehr dankbar! <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1380810</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380810</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Mon, 08 Oct 2007 21:15:54 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 01:27:23 GMT]]></title><description><![CDATA[<p>Sceletor schrieb:</p>
<blockquote>
<p>.filmor schrieb:</p>
<blockquote>
<p>Maps werden immer nach ihrem Schlüsseltyp sortiert. Damit das funktioniert, brauchst du ein Vergleichskriterium.<br />
Standardmäßig ist der Comparetyp std::less&lt;KeyType&gt; und std::less ist mit dem &lt;-Operator definiert.<br />
Du hast also 3 Möglichkeiten, den Code zum Laufen zu bringen:<br />
1. Du schreibst einen &lt;-Operator für MyClass (ist aber nur sinnvoll, wenn ein solcher Vergleich tatsächlich logisch möglich ist)<br />
2. Du spezialisierst das std::less-Template für deine Klasse<br />
3. Du schreibst eine eigene Vergleichsfunktion (das Sinnvollste, wenn du nur in einem Kontext eine solche Map anlegst.</p>
</blockquote>
<p>Mein Problem ist, daß ich leider keine der drei möglichen Lösungen nachvollziehen kann und auch nicht weiss, welche davon nun für mich die einfachste/effektivste wäre.</p>
<p>Ich glaube zu verstehen, daß es darum geht, der STL beizubringen, wie sie meine Koordinaten nach Größe sortieren kann. Da wäre ja logisch einfach (entweder X oder Y Wert höher gewichten), aber wie und vor allem wo muss ich das implementieren.<br />
Wäre für Codebeispiele sehr dankbar! <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>Genau darum gehts, um ein Vergleichskriterium. Auf welcher Ebene du dieses Kriterium implementierst, ist die Sache die du entscheiden musst, und das sind die obigen drei Punkte. Wie du vielleicht weißt, hat die std::map nicht nur den key_type und den value_type als Templateparameter, sondern (neben dem Allocator, den alle container haben) auch einen sogenannten Comparator, das ist ein Functor, der zwei key_types miteinander vergleicht. Default für den Comparator ist std::less.</p>
<p>Ich roll mal die Punkte von filmor von hinten auf: Punkt 3 bedeutet, einen eigenen Comparator zu schreiben. Das ist eine Klasse, die folgendes besitzen muss:<br />
- einen Standardkonstruktor (kannder implizit durch den COmpiler generierte sein)<br />
- einen <code>bool operator()(const T&amp;, const T&amp;)</code> , der die zu vergleichenden Objekte streng ordnet. Beispiel hierfuer wäre</p>
<pre><code class="language-cpp">struct CoordCompare {
  bool operator() (const Coordinate&amp; a, const Coordinate&amp; b) {
    //Wenn x-Koordinaten gleich sind ordne nach y-Koordinaten, sonst nach x-Koordinaten
    return (a.x==b.x) ? (a.y&lt;b.y) : (a.x&lt;b.x);
  }
};

//benutzung dann wie folgt:
std::map&lt;Coordinate, Stellarobject*, CoordCompare&gt;; //benutze CoordCompare fuer die Ordnung der Coordinates
</code></pre>
<p>Zweite Möglichkeit ist, dem Compiler statt einem eigenen Comparator nur zu sagen, wie er std::less&lt;&gt; für Coordinaten zu verstehen hat, das waere dann eine Spezialisierung des templates:</p>
<pre><code class="language-cpp">namespace std {
template&lt;&gt;
struct less&lt;Coordinate&gt; {
  bool operator() (const Coordinate&amp; a, const Coordinate&amp; b) {
    //Wenn x-Koordinaten gleich sind ordne nach y-Koordinaten, sonst nach x-Koordinaten
    return (a.x==b.x) ? (a.y&lt;b.y) : (a.x&lt;b.x);
  }
};
}

//Nutzung:
std::map&lt;Coordinate, Stellarobject*&gt;; //benutzt automatisch die Spezialisierung von std::less&lt;Coordinate&gt;
</code></pre>
<p>Das sieht gleich aus, allerdings musst du jetzt bei Containern (und bei anderen Strukturen, die std::less&lt;&gt; nutzen) nicht mehr explizit den Comparator angeben sondern kannst dich darauf verlassen, dass der Compiler immer deine Spezialisierung findet.</p>
<p>Das allgemeinste ist Punkt 1, nämlich die Angabe eines operator&lt; für deine Coordinate Klasse. Damit kannst du nichtnur Abfragen wie &quot;if (coordiA &lt; coordiB)&quot; realisieren. std::less benutzt nämlich defaultmäßig (das heißt, wenn man nicht wie in Punkt 2 ne Spezialisierung angibt) den operator&lt; (Die Implementierung besteht meist aus der kleinen Zeile &quot;return a&lt;b;&quot;). Deshalb hat dein Compiler auch gemeckert, weil std::less den op&lt; für Coordinate aufgerufen hat, dens aber nicht gibt. Die Implementierung ist simpel:</p>
<pre><code class="language-cpp">struct Coordinate {
//...

public:
  bool operator&lt; (const Coordinate&amp; other) const {
    //Wenn x-Koordinaten gleich sind ordne nach y-Koordinaten, sonst nach x-Koordinaten
    return (x==other.x) ? (y&lt;other.y) : (x&lt;other.x);
  }
//...
};
</code></pre>
<p>(Bin mir grad nicht ganz sicher ob man op&lt; auch außerhalb der Klasse mit zwei Argumenten implementieren kann und welche Version die Gurus da befürworten, aber so funktionierts auf jeden Fall)</p>
<p>Alle drei Varianten funktionieren für deine map gleich gut.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380920</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380920</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 09 Oct 2007 01:27:23 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 12:10:50 GMT]]></title><description><![CDATA[<p>Also, ich habe den Comparator nun implementiert und er läuft auch prima, aber wenn ich nun was (erstmal ein Starsystem) in die Map stecken will, kommt:</p>
<blockquote>
<p>matching function for call to `Galaxymap::add_item(Starsystem&amp;, int&amp;, int&amp;)'<br />
Galaxymap.hpp:15: note: candidates are: void Galaxymap::add_item(Stellarobject*, int, int)</p>
</blockquote>
<p>und das, obwohl Starsystem (wie von Th erklärt) von der abstrakten Klasse Stellarobject erbt.</p>
<p>Was muss ich an dem Code noch ändern?</p>
<pre><code>battlefield.add_item(new_System, x_pos, y_pos);
</code></pre>
<pre><code class="language-cpp">class Starsystem : public Stellarobject
</code></pre>
<pre><code class="language-cpp">#ifndef STELLAROBJECT_HPP
#define STELLAROBJECT_HPP

class Stellarobject
{
};

#endif
</code></pre>
<p>EDIT: Schon rausgefunden,</p>
<pre><code class="language-cpp">battlefield.add_item(&amp;new_System, x_pos, y_pos);
</code></pre>
<p>war die Lösung.</p>
<p>Wobei... Ist das richtig so? Und warum kann ich es nur als Referenz, nicht aber als Zeiger oder &quot;ohne alles&quot; (was wohl eine Kopie wäre dann) übergeben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1381199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1381199</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Tue, 09 Oct 2007 12:10:50 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 13:26:28 GMT]]></title><description><![CDATA[<p>Was ist 'new_system' denn?<br />
Anscheinend eine lokale Variable vom Type 'Starsystem'.<br />
Da du aber Zeiger auf Stellarobjekte in deiner Liste verwaltest, mußt du ein mit 'new' allokiertes Starsystem übergeben.<br />
Andernfalls wäre das Objekt ja nur temporär vorhanden (ab Blockende wäre der Speicher wieder überschrieben).<br />
Hier nun die korrekte Version:</p>
<pre><code class="language-cpp">Starsystem *new_system = new Starsystem(...); // Parameter?
battlefield.add_item(new_System, x_pos, y_pos);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1381290</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1381290</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Tue, 09 Oct 2007 13:26:28 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 13:49:44 GMT]]></title><description><![CDATA[<p>Wie schon oben angedeutet musst du dich fuer dein Design fuer eine von zwei Varianten entscheiden, was die Speicherung angeht:<br />
entweder, du uebergibst deinem Container einen Zeiger auf ein bestehendes Objekt, oder das Objekt selbst. Wenn du ihm einen Zeiger uebergibst, sollte das kein Zeiger auf ein lokales Objekt sein, da sonst irgendwann ein Zeiger auf ein nichtmehr existierendes Objekt in deinem Container rumliegt. Daher musst du wie th schon sagt die Objekte mit new erzeugen (delete spaeter nicht vergessen!).<br />
Wenn du ihm das Objekt selbst zum Kopieren und Einfuegen uebergeben willst, gibt es zwei Probleme:<br />
erstens muesstest du fuer jede Klasse, von denen du Objekte in den Container legen willst, eine eigene Einfuegemethode schreiben. Denn sowas wie add_item(Stellarobject&amp; newobject) funktioniert nicht, da dann nur der Basisklassenteil des Objekts kopiert wuerde und alle zusaetzlichen informationen verloren gehen (splicing). Zweitens kannst du in einen Container nicht Objekte verschiedenen Typs packen, also musst du trotzdem mit Pointern auf stellarobject arbeiten.<br />
Falls du (berechtigterweise) davor zurueckschreckst, die Objekte alle mit new und delete selbst verwalten zu muessen, gibts einen oft genutzten Ansatz: Du gibst der Klasse stellarobject die vieruelle methode Clone() mit, die das jeweilige Objekt dupliziert und einen Zeiger darauf zurueckgibt. Der add_item methode gibst du dann einen Zeiger auf das (moeglicherweise lokale) Objekt, die methode ruft davon Clone() auf, um einen Klon zu erstellen, der laenger als das lokale Objekt lebt. Das deleten dieses KLons muss dann der verwaltende Container uebernehmen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1381319</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1381319</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 09 Oct 2007 13:49:44 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 14:39:20 GMT]]></title><description><![CDATA[<p>EDIT:<br />
Hatte den Beitrag von Pumuckl nicht gesehen..<br />
Ich werde versuchen, den Ansatz von Th zu benutzen, d.h. mit Zeigern und new/delete arbeiten.<br />
Dann ist es doch ausreichend, nach dem Spiel einfach die Zeiger auf die Stellarobjects in der Map alle durchzugehen und die Objekte dazu zu deleten, oder?</p>
<p>Davor hab ich aber noch ne andere Frage:<br />
Wie bekomme ich denn die Zeiger auf Stellarobjekte, nachdem ich sie aus der Liste wieder herausgeholt habe, wieder zu Instanzen von Starsystem, Blackhole etc. &quot;zurückgebaut&quot;?</p>
<p>Muss ich da casten?</p>
<p>Meine Funktion sieht jetzt erstmal so aus:</p>
<pre><code class="language-cpp">//Get all the systems out of the map and render them
void Game::render_starsystems()
{
	for (int n=0;n&lt;field_width;n++)
	{
		for (int m=0;m&lt;field_height;m++)
		{
			if(battlefield.check_pos(n,m)) // Do this only if mapfield is occupied
			{
				list&lt;Stellarobject*&gt; temp_list;
				temp_list=battlefield.get_list(n,m); //Get the list out of occupied field

				list&lt;Stellarobject*&gt;::iterator it = temp_list.begin(); //Iterate over the list and render the lists objects

				while (it != temp_list.end())
				{
					it-&gt;render();
					it++;
				}
			}
		}
	}
}
</code></pre>
<p>und der Compiler meckert, weil er render() nicht kennt (die ist ja auch nur in der Klasse Starsystem definiert, nicht in Stellarobject).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1381379</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1381379</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Tue, 09 Oct 2007 14:39:20 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 15:23:32 GMT]]></title><description><![CDATA[<p>Du solltest dich evtl. erst mal ein wenig intensiver mit OOP beschäftigen, d.h. wie erstelle ich komplexere Klassen (-hierarchien) in C++.<br />
Ansonsten befürchte ich, daß dein Code dir irgendwann zu groß und komplex wird.</p>
<p>Der beste Ansatz für das Rendern besteht dadrin, einfach eine virtuelle Methode 'render' in der Basisklasse zu definieren, welche dann von den abgeleiteten Klassen implementiert wird.</p>
<p>Je nach Anzahl der abgeleiteten Objekte mußt du für dich entscheiden, ob du evtl. noch Zwischen-(Basis)klassen erstellst, welche Gemeinsamkeiten mehrerer Klassen implementieren.<br />
Der letzte Ausweg sollte sein, ein &quot;dynamic-cast&quot; zu benutzen, um zu schauen, um welches Stellarobjekt es sich handelt.<br />
Sobald du merkst, daß du an verschiedenen Stellen im Source &quot;switches&quot; benötigst, dann überleg dir, ob du nicht besser eine virtuelle Methode dafür bereitstellst.</p>
<p>P.S.<br />
Deine Methode 'get_list' sollte besser eine Referenz auf die Liste zurückgeben, damit die Liste nicht beim Rendern immer kopiert wird (wenn auch nur die Zeiger):</p>
<pre><code class="language-cpp">Stellar_list &amp; temp_list = battlefield.get_list(n,m); // typedef benutzen!!!
</code></pre>
<p>So langsam kriege ich selber wieder Lust, an einem Weltraumspiel zu arbeiten (vor Jahren hatte ich mal ein Spiel namens &quot;Universe&quot; entwickelt, bevor ich vorletztes Jahr bei Ascaron an &quot;DarkStar One&quot; mitprogrammiert hatte).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1381426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1381426</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Tue, 09 Oct 2007 15:23:32 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Tue, 09 Oct 2007 15:48:00 GMT]]></title><description><![CDATA[<p>Wegen dem Beschäftigen mit OOP, insbesondere Klassenhierarchien:</p>
<p>Gibts da was besonders sinnvolles im Web zu? Ich finde immerwieder Tonnen von Sachen zu den Basics (Variablen, Arrays, if,for, while...) aber zu komplexeren Themen hab ich noch nichts gesehen, also wäres nett, wenn du mir nen Link oder Buchtitel anempfehlen könntest (oder natürlich auch jeder andere hier).</p>
<p>Und wofür soll ich in dem Code ein typedef benutzen?</p>
<p>Um mal was zum Hintergrund der Sache zu erzählen:<br />
Ich arbeite jetzt seit nem guten Jahr immerwieder hobbymäßig an meinem Spiel, aber das Coden ist in der Vergangenheit stark in den Hintergrund getreten, da ich mich eher mit Zeichnen und Designdoc schreiben beschäftigt habe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1381444</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1381444</guid><dc:creator><![CDATA[Sceletor]]></dc:creator><pubDate>Tue, 09 Oct 2007 15:48:00 GMT</pubDate></item><item><title><![CDATA[Reply to Objekte als Parameter und in multimaps on Wed, 10 Oct 2007 13:05:43 GMT]]></title><description><![CDATA[<p>Hi Sceletor,<br />
also als Buch kann ich dir auf jeden Fall das Standard-Buch vom Erfinder von C++ empfehlen: B. Stroustrup - Die C++ Programmiersprache (4. Auflage).<br />
Das Buch ist zwar nicht ganz billig, aber es vermittelt einen sehr guten Überblick über alle Programmiertechniken als auch die Verwendung der C++ Standard Bbliothek (ursprünglich STL genannt).<br />
Und es gibt eigene Kapitel zum Design von C++ Programmen und weitere interessante Sachen (Templates, Exceptions).</p>
<p>Den typedef habe ich extra benutzt, damit man nicht immer wieder die komplette template-Schreibweise hinschreiben muß.<br />
Außerdem hat es den Vorteil, daß du evtl. den verwendeten Datentypen leichter wechseln könntest (z.B. wenn du doch lieber std::vector statt std::list benutzen willst), nämlich nur an der einen Stelle in der Header-Datei.</p>
<p>Mir hat es den Anschein, du programmierst einfach so drauf los und das kann, je größer das Programm wird, immer schwieriger werden, ein gutes und einheitliches Design zu verwenden.</p>
<p>Du solltest zuerst damit anfangen, dir die Basisklassen und darauf aufbauenden Klassen genau zu überlegen, ehe du einzelne Methoden implementierst.<br />
Ein gutes Klassendesign führt meistens zu kleineren und überschaubareren Programmen.</p>
<p>Ich will dir auf keinen Fall den Mut nehmen weiterzumachen, sondern dich einfach nur auf bestimmte Fallstricke bei C++ hinweisen.</p>
<p>Und mit welcher GUI willst du denn die Sterne und schwarzen Löcher etc. zeichnen?</p>
<p>Wenn du willst, kann ich dir ja bei deinem Projekt helfen.<br />
Ich selber entwickle auch Spiele (privat zwar keine 3D, aber trotzdem ansehbar, s.a. <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-193889.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-193889.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1382065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1382065</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Wed, 10 Oct 2007 13:05:43 GMT</pubDate></item></channel></rss>