iterator dereferenzieren
-
hio.
woher weiß ich wann ich einen iterator beim zugriff auf das element auf das er zeigt dereferenzieren muss, und wann nicht?
2 beispiele: (stark gekürzt)
// Variablen list<Raumschiff*> lSchiffe; list<Raumschiff*>::iterator i; [...] // Liste durchlaufen und alle Raumschiffe starten lassen for (i = lSchiffe.begin(); i != lSchiffe.end(); ++i) { (*i)->Starten(); }
hier muss ich nun also dereferenzieren.
weshalb braucht man hier eigentlich klammern beim dereferenzieren?
weshalb wird hier nicht der .-Operator sondern -> benutzt?und das hier:
// Variablen map<string, int> Punktetabelle; // Map map<string, int>::iterator i; // Iterator für die Map pair<string, int> Spieler; // Paar-Objekt für die Map [...] // Prüfen ob ein entsprechender Eintrag gefunden wurde if (i != Punktetabelle.end()) { // Ja, dann Spielerdaten ausgeben cout << "Spieler \"Peter\" wurde gefunden." << endl; cout << "Er hat " << i->second << " Punkte erreicht." << endl; }
hier wird nicht dereferenziert, und klammern brauchts auch nicht. warum?
und woher weiß ich wann ich deferenzieren und wann ich klammern setzen muss?
gruß,
chris
-
Mach dir einfach mal klar was ein Iterator ist: Ein Zeiger auf ein Element im deque. Wenn du das Element im deque bearbeiten willst (z.B einen neuen Wert setzen), dann musst du den Iterator dereferenziern. Sind im deque allerdings Strukturen/Instanzen einer Klasse gespeichert kannst du auf die mit dem -> Operator(?) zugreifen. Ich hoffe dir ist nun ein bisschen klarer wie das funktioniert.
edit, ich habe deque geschrieben, das gilt auch für maps, lists und co.
-
flammenvogel schrieb:
Mach dir einfach mal klar was ein Iterator ist: Ein Zeiger auf ein Element im deque. Wenn du das Element im deque bearbeiten willst (z.B einen neuen Wert setzen), dann musst du den Iterator dereferenziern. Sind im deque allerdings Strukturen/Instanzen einer Klasse gespeichert kannst du auf die mit dem -> Operator(?) zugreifen. Ich hoffe dir ist nun ein bisschen klarer wie das funktioniert.
edit, ich habe deque geschrieben, das gilt auch für maps, lists und co.
ich glaube du verstehst nicht ganz mein problem oder?
oder aber ich verstehe deine antwort in bezug auf mein problem nicht.
-
chris' schrieb:
ich glaube du verstehst nicht ganz mein problem oder?
oder aber ich verstehe deine antwort in bezug auf mein problem nicht.Ich glaube du hast seine Antwort nicht richtig gedeutet.
Ein Iterator ist sozusagen ein Zeiger auf ein Element im Container.
Im 2ten Beispiel ist das Element ein pair<string, int>, somit greifst du mittels it->second auf den int zu. Im ersten Beispiel allerdings ist das Element ein Zeiger auf Raumschiff. Ein Zeiger auf Raumschiff hat keine Methode Starten, nur ein Raumschiff-Objekt hat diese. Mit "den Klammern (+ op*)" dereferenzierst du den Zeiger auf den Zeiger auf Raumschiff, mit -> dereferenzierst du den Zeiger auf Raumschiff und rufst die entsprechende Methode auf.
-
genau, das was finix meint, meine ich auch. Du hast da einen Sonderfall nämlich ist der Iterator in dem Beispiel ein zeiger auf einen Zeiger den du zweimal dereferenzieren musst.
-
ahh ok, nu hab ichs...danke
-
chris' schrieb:
cout << "Er hat " << i->second << " Punkte erreicht." << endl;
hier wird nicht dereferenziert, und klammern brauchts auch nicht. warum?
und woher weiß ich wann ich deferenzieren und wann ich klammern setzen muss?
gruß,
chris
Natürlich wird hier derefenziert.
i->second ist doch nur eine andere Schreibweise für (*i).second.
Die Klemmern musst du dann setzen, wenn es auch anders gehen könnte (-aber nicht kann).
*i.second könnte ja auch so aufgefasst werden: *(i.second).