Generics in C++: Wozu sie dienen und wie man sie in der Praxis einsetzt

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Was sind Generics in C++ und wozu dienen sie?

In der Welt der modernen Programmierung ist die Wiederverwendung von Code eines der Schlüsselprinzipien. Wenn Sie eine Summenfunktion für int und dann für double und float schreiben, möchten Sie früher oder später Doppelarbeit vermeiden. Genau hier kommen Generics (generische Programmierung) ins Spiel. In C++ wird dieses Konzept durch Vorlagen (templates) umgesetzt.

Generics ermöglichen es, Code zu schreiben, der mit jedem Datentyp funktioniert, ohne Einbußen bei der Leistung (im Gegensatz zu virtuellen Funktionen oder void*). Der Compiler generiert für jeden konkreten Typ eine separate Version der Funktion oder Klasse, was maximale Ausführungsgeschwindigkeit bietet.

In diesem Artikel werden wir untersuchen, wozu Generics in C++ dienen, wie man sie richtig deklariert und in der Praxis einsetzt, sowie typische Fehler und fortgeschrittene Techniken betrachten.



Grundlagen der Syntax: Wie man eine Vorlage deklariert und verwendet

Eine Vorlage in C++ wird mit dem Schlüsselwort template und spitzen Klammern <> deklariert, in denen der Typparameter (normalerweise typename oder class) angegeben wird.

Funktionsvorlage

Das einfachste Beispiel ist eine Funktion, die das Maximum von zwei Werten zurückgibt:

template <typename T>T max(T a, T b) {    return (a > b) ? a : b;}

// Verwendung:int main() { std::cout << max(3, 7) << std::endl; // 7 std::cout << max(3.14, 2.71) << std::endl; // 3.14 std::cout << max('a', 'z') << std::endl; // z return 0;}

Beachten Sie: Der Compiler leitet den Typ T basierend auf den übergebenen Argumenten selbst ab. Wenn Sie den Typ explizit angeben möchten, können Sie max<double>(3.14, 2.71) schreiben.



Klassenvorlage

Vorlagen funktionieren auch mit Klassen. Ein klassisches Beispiel ist ein einfacher Container „Paar“:

template <typename T1, typename T2>class Pair {private:    T1 first;    T2 second;public:    Pair(T1 f, T2 s) : first(f), second(s) {}    T1 getFirst() const { return first; }    T2 getSecond() const { return second; }};

// Verwendung:Pair<int, std::string> student(1, "Alice");std::cout << student.getFirst() << " " << student.getSecond();

Hier sind T1 und T2 Vorlagenparameter, die beliebige Typen sein können.



Praktische Beispiele: Von einfachen Containern bis zu Algorithmen

Betrachten wir einige reale Szenarien, in denen Generics unverzichtbar sind.



Universelle Sortierung

Schreiben wir eine Vorlagenfunktion zum Sortieren eines Arrays beliebigen Typs, der den Operator < unterstützt:

template <typename T>void bubbleSort(T arr[], int n) {    for (int i = 0; i < n - 1; ++i)        for (int j = 0; j < n - i - 1; ++j)            if (arr[j] > arr[j + 1])                std::swap(arr[j], arr[j + 1]);}

// Beispiel:int intArr[] = {5, 2, 8, 1};bubbleSort(intArr, 4); // Funktioniert mit int

double dblArr[] = {3.14, 2.71, 1.41};bubbleSort(dblArr, 3); // Funktioniert mit double


Stack mit beliebigem Datentyp

Implementieren wir einen einfachen Stack basierend auf einer Vorlage:

template <typename T>class Stack {private:    std::vector<T> elements;public:    void push(const T& value) { elements.push_back(value); }    void pop() { if (!elements.empty()) elements.pop_back(); }    T top() const { return elements.back(); }    bool empty() const { return elements.empty(); }};

// Verwendung:Stack<int> intStack;intStack.push(10);intStack.push(20);std::cout << intStack.top(); // 20


Algorithmus „Suchen und Ersetzen“

Eine Vorlagenfunktion, die alle Vorkommen eines Wertes durch einen anderen in einem Container ersetzt:

templa                

Blogs

Buchempfehlungen