Menu
CoddyTech

Klassen-Templates

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 65 von 104.

So wie Funktionstemplates es dir ermöglichen, typspezifische Funktionen zu schreiben, kannst du mit Klassentemplates typspezifische Klassen erstellen. So funktionieren Container wie std::vector: Du definierst die Struktur einmal, und der Compiler erzeugt für jeden verwendeten Typ eine eigene Version.

template <typename T>
class Box {
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
    void setValue(T v) { value = v; }
};

int main() {
    Box<int> intBox(42);
    Box<std::string> strBox("Hello");
    
    std::cout << intBox.getValue() << std::endl;  // 42
    std::cout << strBox.getValue() << std::endl;  // Hello
}

Beim Erstellen von Objekten aus Klassenvorlagen gibst du den Typ normalerweise in spitzen Klammern an. Seit C++17 kann der Compiler ihn auch aus den Konstruktorargumenten ableiten (Box b(42); erstellt ein Box<int>), aber wenn keine Argumente vorhanden sind, aus denen er ihn ableiten kann, musst du den Typ angeben. Der Compiler erzeugt dann eine vollständige Klassendefinition für diesen spezifischen Typ.

Klassenvorlagen können mehrere Typparameter und sogar Nicht-Typparameter wie Ganzzahlen haben:

template <typename T, int Size>
class FixedArray {
    T data[Size];
public:
    T& operator[](int index) { return data[index]; }
    int size() const { return Size; }
};

FixedArray<double, 5> arr;  // Array aus 5 double-Werten
arr[0] = 3.14;

Wenn du Member-Funktionen außerhalb der Klasse definierst, musst du die Template-Deklaration wiederholen:

template <typename T>
class Container {
    T* data;
public:
    Container();
    ~Container();
};

template <typename T>
Container<T>::Container() : data(nullptr) {}

template <typename T>
Container<T>::~Container() { delete data; }

Klassenvorlagen bilden die Grundlage der generischen Programmierung in C++ und ermöglichen es dir, wiederverwendbare Datenstrukturen zu schreiben, die mit jedem Typ funktionieren.

challenge icon

Aufgabe

Einfach

Lass uns mithilfe von Klassenvorlagen ein generisches Speichersystem erstellen, das einen flexiblen Container für beliebige Datentypen bereitstellt. Du organisierst deine Vorlagenklasse in einer Headerdatei und zeigst ihre Vielseitigkeit mit verschiedenen Typen in deinem Hauptprogramm.

Du erstellst zwei Dateien:

  • Storage.h: Definiere eine Klassenvorlage namens Storage, die als einfacher Container für einen einzelnen Wert mit einigen nützlichen Operationen dient:

    Deine Storage-Vorlage sollte Folgendes enthalten:

    • Ein privates Element zum Speichern des Werts
    • Einen Konstruktor, der einen Anfangswert entgegennimmt
    • Eine Methode getValue(), die den gespeicherten Wert zurückgibt
    • Eine Methode setValue(), die den gespeicherten Wert aktualisiert
    • Eine Methode isEmpty(), die true zurückgibt, wenn der Wert dem standardmäßig konstruierten Wert des Typs T entspricht, andernfalls false

    Erstelle außerdem eine Klassenvorlage namens Pair mit zwei Typparametern, die zwei zusammengehörige Werte speichert:

    • Private Elemente für den ersten und den zweiten Wert (die möglicherweise unterschiedliche Typen haben)
    • Einen Konstruktor, der beide Werte initialisiert
    • Die Methoden getFirst() und getSecond(), um die jeweiligen Werte abzurufen
    • Eine Methode display(), die Folgendes ausgibt: (<first>, <second>)
  • main.cpp: Lies vier Eingaben ein (jeweils in einer separaten Zeile):
    1. Einen ganzzahligen Wert
    2. Einen neuen ganzzahligen Wert
    3. Einen Zeichenkettenwert
    4. Einen double-Wert

    Führe mit deinen Vorlagen Folgendes vor:

    1. Erstelle ein Storage<int> mit der ersten Ganzzahl und gib Folgendes aus: Int storage: <value>
    2. Aktualisiere es mithilfe von setValue() mit der zweiten Ganzzahl und gib anschließend Folgendes aus: Updated: <value>
    3. Erstelle ein Storage<std::string> mit der eingegebenen Zeichenkette und gib Folgendes aus: String storage: <value>
    4. Prüfe, ob der Zeichenkettenspeicher leer ist, und gib Folgendes aus: Is empty: <true/false> (gib true oder false aus)
    5. Erstelle ein Pair<std::string, double> mit der Zeichenkette und dem double-Wert und rufe anschließend display() auf
    6. Erstelle ein Pair<int, int> mit beiden ganzzahligen Eingaben und rufe anschließend display() auf

Zum Beispiel bei den Eingaben 42, 100, Hello und 3.14:

Int storage: 42
Updated: 100
String storage: Hello
Is empty: false
(Hello, 3.14)
(42, 100)

Beachte, wie dieselbe Storage-Vorlage nahtlos mit Ganzzahlen und Zeichenketten funktioniert und wie Pair unterschiedliche Typen miteinander kombinieren kann. Der Compiler erzeugt für jede verwendete Typkombination separate Klassendefinitionen. Denke daran, für Vorlagen mit einem einzelnen Typ die Syntax template <typename T> und für Vorlagen mit mehreren Typparametern template <typename T, typename U> zu verwenden.

Probier es selbst

#include <iostream>
#include <string>
#include "Storage.h"

using namespace std;

int main() {
    // Eingaben einlesen
    int intValue1;
    int intValue2;
    string strValue;
    double doubleValue;
    
    cin >> intValue1;
    cin >> intValue2;
    cin >> strValue;
    cin >> doubleValue;
    
    // TODO: Storage<int> mit der ersten Ganzzahl erstellen und ausgeben: Int storage: <value>
    
    // TODO: Mit der zweiten Ganzzahl über setValue() aktualisieren und ausgeben: Updated: <value>
    
    // TODO: Storage<std::string> mit der Zeichenketteneingabe erstellen und ausgeben: String storage: <value>
    
    // TODO: Prüfen, ob der String-Speicher leer ist, und ausgeben: Is empty: true/false
    
    // TODO: Pair<std::string, double> mit der Zeichenkette und dem double-Wert erstellen und display() aufrufen
    
    // TODO: Pair<int, int> mit beiden Ganzzahlen erstellen und display() aufrufen
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C++-Compiler