Dinge assoziieren
Viele Programmiersprachen bieten assoziative Container: Container, deren Index
aus beliebigen Objekten bestehen kann, statt nur auf Integer beschränkt zu sein.
C++ ist da keine Ausnahme. Genaugenommen bietet es mehrere verschiedene
Varianten für unterschiedliche Ansätze. Eine davon: std::map.
Video
Code
#include <iostream>
#include <string>
#include <map>
int main()
{
std::map<std::string, std::string> capital
{
{ "Deutschland", "Berlin" },
{ "Polen", "Warschau" },
{ "Schweden", "Stockholm" },
{ "Italien", "Rom" }
};
std::cout << capital["Deutschland"] << std::endl;
capital["Frankreich"] = "Paris";
std::cout << capital.at("Frankreich") << std::endl;
std::cout << capital["Norwegen"] << std::endl;
std::cout << capital.at("Finnland") << std::endl;
}
Erklärung
Der Quelltext ist fast selbsterklärend: wir möchten (das Standardbeispiel...) zu
einem Land seine Hauptstadt speichern und ggf. abrufen können. Dafür bietet sich
ein assoziativer Container an: als Index wird der Name des Landes verwendet, als
Wert der Name der Hauptstadt. Wie alles in C++ müssen natürlich Schlüssel und
Wert streng typisisert sein. std::map ist daher ein Template, welches
mindestens zwei Parameter nimmt: den Schlüsseltyp (in unserem Fall
std::string) und den Werttyp (in unserem Fall ebenfalls std::string).
Mittels einer Initialisierungsliste wird unsere capital-Map schon mal
vorbelegt: paarweise werden die Abbildungen vorbelegt.
Das Auslesen der Map ist dann analog zum Indexzugriff in einem Array:
operator[] wird mit dem Schlüssel aufgerufen und liefert den dahinter
stehenden Wert zurück. Der Operator kann ebenso genutzt werden, um etwas in die
Map einzufügen: er liefert eine schreibbare Referenz auf das Objekt mit dem
betreffenden Schlüssel. Hier liegt auch schon eine der Stolperfallen von
std::map begraben: wenn ein Schlüssel nicht vorhanden ist, dann wird er
eingefügt, um die schreibbare Referenz zurückliefern zu können. Um das zu
vermeiden, gibt es eine zweite Variante für den Indexzugriff, die
Java-Programmierern etwas bekannter vorkommen sollte: die Methode at() nimmt
ebenso einen Schlüssel und liefert dessen Wert. Im Gegensatz zu operator[]
wird allerdings bei fehlendem Schlüssel der Wert nicht angelegt, sondern eine
Exception geworfen. Deswegen verhalten sich die Zeilen 20 und 21
unterschiedlich: 20 gibt einen leeren String aus (der mittels
Default-Konstruktor neu angelegte Wert für den Schlüssel "Norwegen"), 21 wirft
eine std::out_of_range-Exception um anzuzeigen, dass der Wert "Finnland" nicht
in der Map vorhanden ist.