C++-Standardbibliothek
Die C++-Standardbibliothek ist die zur Programmiersprache C++ gehörende Programmierbibliothek, also eine Zusammenstellung von Algorithmen, die in der Programmiersprache C++ geschrieben sind und fest zur Programmiersprache C++ gehören, so dass sie bei der Lösung von Programmierproblemen immer als vorhanden vorausgesetzt und angewendet werden können.
Überblick
Die C++-Standardbibliothek stellt verschiedene generische Container, Funktionen zu deren Manipulierung, Funktionsobjekte, generische Zeichenketten (auch "Strings" genannt), Datenströme u.a. für den Dateizugriff, Unterstützung von Sprachmitteln sowie einfache Funktionen beispielsweise zur Bildung der Quadratwurzel zur Verfügung.
In der C++-Standardbibliothek ist auch die gesamte Standardbibliothek der Programmiersprache C enthalten.
Entstehung
Die für C++ neuentwickelte Bibliothek hat ihren Ursprung schon in den 1980er Jahren, wurde aber im Laufe der Standardisierung durch den Einfluss einer bei Hewlett-Packard entwickelten Bibliothek namens Standard Template Library stark überarbeitet..
Bestandteile der C++-Standardbibliothek
Die C++-Standardbibliothek bietet:
- Container (Behälterklassen)
- Iteratoren
- Algorithmen
- Funktionsobjekte
- Zeichenketten
- Ein-/Ausgabe
- Lokalisierung
- Numerik
Die meisten Komponenten der C++-Standardbibliothek liegen in Form von Templates vor. Das Template-Konzept hat den großen Vorteil der Wiederverwendbarkeit, so können zum Beispiel durch einfache Deklaration Container für beliebige Datentypen erzeugt werden; Algorithmen gelten für eine ganze Reihe von Datentypen.
Container
Container (Behälterklassen) sind Datenstrukturen, die aus einer Anzahl verschiedener Objekte des selben Datentyps bestehen. Die grundlegenden Container der C++-Standardbibliothek sind:
sequentielle Container:
- Vektoren (engl. vector)
- doppelt verkettete Listen (list)
- Warteschlangen (queue)
- Warteschlangen mit zwei Enden (deque)
- Warteschlangen mit Prioritäten (priority_queue)
- Stapel (stack)
assoziative Container:
- Mengen (set, multi_set)
- Assoziative Felder (map, multi_map)
- Bitmengen (bitset)
In sequentiellen Containern sind die Objekte linear angeordnet und werden über ihre Position angesprochen. In assoziativen Containern werden die Objekte in einer Baumstruktur unterhalten. Der Zugriff erfolgt hier mit Hilfe von Schlüsseln.
Iteratoren
Jeder Container verfügt über verallgemeinerte Zeiger, die so genannten Iteratoren (von lateinisch iterare: wiederholen), mit deren Hilfe über die Elemente eines Containers iteriert sowie auf einzelne Elemente des Containers zugegriffen werden kann.
Bezogen auf ihre Aufgabe sind die Iteratoren reine Zugriffsobjekte. Sie entkoppeln die Algorithmen von den Daten, so dass diese typenunabhängig werden. Bei den Iteratoren gibt es folgende Kategorien:
- Eingabe-Iteratoren: lesenden Zugriff für einen einzelnen Durchlauf
- Ausgabe-Iteratoren: schreibender Zugriff für einen einzelnen Durchlauf
- Forward-Iteratoren: sequentieller Zugriff mit relativem Bezug auf Iteratoren, in eine Richtung
- Bidirektionale Iteratoren: wie Forward-Iteratoren jedoch in beide Richtungen
- Iteratoren mit wahlfreiem Zugriff: wahlfreier Zugriff, auch mit Index-Operator ([])
Algorithmen
Algorithmen sind Funktionen mit bestimmten Manipulationsvorschriften, die auf einen Container angewendet werden. Dabei sind sie unabhängig von der speziellen Implementierung der Container. Sie können nur über Iteratoren auf die Elemente in den Containern zugreifen. Sie enthalten u.a. die Standard-Algorithmen der Informatik, wie z.B. Sortieralgorithmen oder Verfahren zur Erzeugung von Zufallszahlen. Die meistbenutzten sind:
for_each
: wendet eine Operation auf alle Elemente eines Datensatzes antransform
: transformiert einen Datensatz mit einer Funktion in einen anderencopy
: kopiert den Datensatz in einen anderensort
: sortiert den Datensatz
Funktionsobjekte
Bei Funktionsobjekten oder Funktoren handelt es sich um Objekte, die genauso aufgerufen werden können wie Funktionen. Bei ihnen ist der Funktionsoperator () mit der Operatorfunktion "operator(){}" überladen. Es sind Objekte, die sich wie Funktionen verhalten, aber trotzdem alle Eigenschaften von Objekten haben. Bei den Funktionsobjekten gibt es folgende Kategorien:
- Generatoren ohne Funktionsparameter f()
- Unäre Funktionen mit einem Funktionsparameter f(x)
- Binäre Funktionen mit zwei Funktionsparametern f(x,y)
Grundsätzlich benötigen die Algorithmen der C++-Standardbibliothek keine Funktionsobjekte mit mehr als zwei Parametern.
Zeichenketten
Die Zeichenketten-Bibliothek (im folgenden String-Bibliothek) definiert ein Klassen-Template basic_string zur Darstellung von Zeichenketten variabler Länge. Die Methoden des Klassen-Templates erlauben String-Manipulationen und -Operationen, wie z.B. das Einfügen, Löschen, Ersetzen und Suchen in Strings. Die wichtigste Zeichenketten-Klasse ist string, die eine Instantiierung von basic_string vom Typ char ist.
Beispiele
std::vector<int> daten(10); // Datenfeld mit int der Länge 10 anlegen
std::vector<int>::iterator dIter(daten.begin()); // Iterator anlegen und initialisieren
// Iterator zeigt auf ersten Eintrag
for (int i=0; // Zähler i initialisieren,
dIter != daten.end(); // for-Schleife solange durchgehen, bis dIter aufs Ende des Datenfeldes zeigt
++i, ++dIter) { // Zähler i erhöhen, Iterator auf den nächsten Eintrag zeigen lassen
*dIter = i; // i dem Datenfeld zuweisen, auf das dIter zeigt
}
// daten: 0 1 2 3 4 5 6 7 8 9
std::vector<int> datenZwei(10);
std::copy( daten.begin(), daten.end(), // welche Daten sollen kopiert werden
datenZwei.begin() ); // und wohin
// datenZwei: 0 1 2 3 4 5 6 7 8 9
// binärer Funktor std::multiplies<int>() braucht zwei Argumente
std::transform( daten.begin(), daten.end(), // auf welchem Bereich soll Algorithmus arbeiten
datenZwei.begin(), // zweite Datenquelle
datenZwei.begin() // wohin sollen Ergebnisse gehen
std::multiplies<int>() ); // miteinander multiplizieren
// datenZwei: 0 1 4 9 16 25 36 49 64 81
// unärer Funktor std::negate<int>() braucht ein Argument
std::transform( daten.begin()+4, daten.end(), // dieses Mal nicht vom Anfang, sondern vom fünften Element an
daten.begin(),
std::negate<int>() ); // Negation
// daten: 0 1 2 3 -4 -5 -6 -7 -8 -9
std::sort( daten.begin(), daten.end() ); // sortieren
// daten: -9 -8 -7-6 -5 -4 0 1 2 3
Siehe auch: C++, Die Standard-C-Bibliothek, Standard Template Library