C++ Kurs

Wenn fertig, bitte Fenster schließen

Lösung zur Lektion "Klassen-Templates"


// Lösung zu Klassentemplates

// Zuerst Dateien einbinden
#include <iostream>

using std::cout;
using std::endl;

// Symbol definieren für int-Stack
#define INT_TEST
// ODER dieses Symbol für einen Demo-Stack
//#define CLASS_TEST

// Definition der Template-Klasse SArray
// Defaultmässig wird Safe-Array für int-Daten erstellt
template <typename T=int>
class SArray
{
    short   size;           // Grösse des Feldes
    T       *pData;         // Zeiger auf Datenfeld
public:
    SArray(short size);
    ~SArray();
    T& operator[] (int index);
};
// Definition der Memberfunktionen
// Konstruktor
template <typename T>
SArray<T>::SArray(short size_)
{
    // Grösse des Feldes merken
    size = size_;
    // Feld anlegen
    pData = new T[size];
}
// Destruktor
template <typename T>
SArray<T>::~SArray()
{
    // Feld freigeben
    delete [] pData;
}
// Überladener Indexoperator
template <typename T>
T& SArray<T>::operator [](int index)
{
    // Falls Index kleiner 0 ist
    if (index<0)
    {
        cout << "Index kleiner 0!\n";
        // Notausgang da noch kein Exception-Handling bekannt
        exit(1);
    }
    // Falls Index über das Feld hinausgreift
    if (index>=size)
    {
        cout << "Index " << index << " überschreitet obere Grenze " << size << "!\n";
        exit(2);
    }
    // Datum zurückgeben
    return pData[index];
}

// Demo-Klasse
class Demo
{
    char *pText;
public:
    // Standardkonstruktor, wird benötigt für Felddefinition
    // in der Safe-Array Klasse
    Demo()
    {
        pText = NULL;
    }
    // Konstruktor für Objekterstellung
    Demo(const char* const pT)
    {
        pText=new char[strlen(pT)+1];
        strcpy(pText,pT);
    }
    // Kopierkonstruktor, wird benötigt wenn aus einem
    // Safe-Array Element ein neues Objekt erstellt wird
    Demo(const Demo& Orig)
    {
        pText = new char[strlen(Orig.pText)+1];
        strcpy(pText,Orig.pText);
    }
    // Destruktor
    ~Demo()
    {
        delete [] pText;
    }
    // Überladener Zuweisungsoperator, wird benötigt wenn einem
    // Safe-Array Element ein Demo Objekt zugewiesen wird
    Demo& operator = (const Demo& rhs)
    {
        if (&rhs == this)
            return *this;
        delete [] pText;
        pText = new char[strlen(rhs.pText)+1];
        strcpy(pText,rhs.pText);
        return *this;
    }
    // Ausgabe-Memberfunktion
    void Print() const
    {
        cout << pText << endl;
    }
};

// main() Funktion
int main()
{

#ifdef INT_TEST
    const int ARRAYSIZE = 10;  // Feldgrösse
    int index;                 // Schleifenzähler

    // Safe-Array mit Standard-Datentyp int anlegen
    SArray<> shortArray(ARRAYSIZE);
    // Safe-Array füllen
    for (index=0; index<ARRAYSIZE; index++)
        shortArray[index] = index;
    // Safe-Array wieder auslesen
    for (index=0; index<ARRAYSIZE; index++)
        cout << index << ". Wert: " << shortArray[index] << endl;
    // Versuch das Element mit dem Index -1 zu lesen
    cout << "Versuch das Element -1 zu beschreiben!\n";
    shortArray[-1] = 111;
#endif

#ifdef CLASS_TEST
    // Safe-Array für Demo-Objekte erstellen
    SArray<Demo> demoArray(3);
    // Erstes und letztes Feldelement belegen
    // Ruft überladenen Zuweisungsoperator von Demo auf!
    demoArray[0] = Demo("Fenster-Nummer 0");
    demoArray[2] = Demo("Fenster-Nummer 2");
    // Demo-Objekte im Safe-Array ausgeben
    demoArray[0].Print();
    demoArray[2].Print();
    // Objekt aus Safe-Array kopieren
    // Ruft Kopierkonstruktor von Demo auf!
    Demo newObject = demoArray[2];
    newObject.Print();
    // Safe-Array Elemente zuweisen
    // Ruft überladenen Zuweisungsoperator von Demo auf!
    demoArray[2] = demoArray[0];
    demoArray[2].Print();

    // Nun über obere Grenze hinausgreifen
    demoArray[5] = Demo("Fehler!");
#endif
}