Verwendung von Templates in den selbst geschriebenen KLassen Liste und ListenContainer
Hier zunächst ohne weiteren Kommentar die Lösung hierfür und ein paar Testbeispiele in der main-Methode (Zur Unterscheidung von der alten Version, wurde den Klassen ein T hintangestellt für "Template"):
Die KLasse ListeT mit Schablone für den Datentyp des Attributs daten
using namespace std;
template <typename meinDATENTYP>
class ListeT
{
public:
ListeT()
{
nachfolger = 0;
}
ListeT(meinDATENTYP indaten)
{
daten = indaten;
nachfolger = 0;
}
ListeT *nachfolger;
meinDATENTYP daten;
};
Code 0-1: ListeT.h
Die KLasse ListenContainerT mit Schablone erzeugt auch Objekte von ListeT mit Schablonendatentyp
using namespace std;
template <typename meinDATENTYP>
class ListenContainerT
{
private:
ListeT<meinDATENTYP> kopfelement;
public:
ListenContainerT()
{
//Zunächst leere Liste erzeugen:
kopfelement.nachfolger = 0;
}
//Übergebenes String in neues Listen-Element packen und dieses an das Ende der Liste hängen
void append(meinDATENTYP daten)
{
ListeT<meinDATENTYP>* element = new ListeT<meinDATENTYP>(daten);
ListeT<meinDATENTYP>* zeiger = &kopfelement;
while(zeiger->nachfolger!=0)
zeiger = zeiger->nachfolger;
zeiger->nachfolger = element;
}
//Refrerenz auf das i-te Listenelement suchen und dessen String-Inhalt zurückgeben
meinDATENTYP get(int index)
{
ListeT<meinDATENTYP>* zeiger = kopfelement.nachfolger;
for(int i=0;i<index;i++)
{
if(zeiger == 0)
return 0;
zeiger = zeiger->nachfolger;
}
return zeiger->daten;
}
//i-tes Listenelement löschen
void del(int index)
{
//Hier muss der Zeiger auf das vorangehende und das nachfolgende Element
//efunden werden.
ListeT<meinDATENTYP>* zeiger = kopfelement.nachfolger;
ListeT<meinDATENTYP>* zeigervor = &kopfelement;
ListeT<meinDATENTYP>* zeigernach = 0;
for(int i=0;i<index;i++)
{
if(zeiger == 0)
return;
zeigervor = zeiger;
zeiger = zeiger->nachfolger;
}
zeigernach = zeiger->nachfolger;
//Vorgänger-Element mit Nachfolger-Element verbinden:
zeigervor->nachfolger = zeigernach;
//Speicher für aktuelles Element freigeben:
delete zeiger;
}
//die ganze Liste löschen.
void clear()
{
ListeT<meinDATENTYP>* zeiger;
ListeT<meinDATENTYP>* zeigervor = &kopfelement;
//Speicher bereinigen:
while(kopfelement.nachfolger != 0)
{
zeiger = kopfelement.nachfolger;
zeigervor = &kopfelement;
while(zeiger->nachfolger != 0)
{
zeigervor = zeiger;
zeiger = zeiger->nachfolger;
}
zeigervor->nachfolger=0;
delete zeiger;
}
}
//Liefert die Länge der Liste zurück
int getSize()
{
int laenge = 0;
ListeT<meinDATENTYP>* zeiger = &kopfelement;
while(zeiger->nachfolger!=0)
{
laenge++;
zeiger = zeiger->nachfolger;
}
return laenge;
}
};
Code 0-2: ListenContainerT.h
In testetemplate.cpp wird ListenContainerT für zwei ganz unterschiedliche Anwendungen eingesetzt
#include <string>
#include <iostream>
#include "ListeT.h"
#include "ListenContainerT.h"
using namespace std;
bool istTrennzeichen(char zeichen, string trennzeichen)
{
for(int i=0;i<trennzeichen.size();i++)
{
if(zeichen == trennzeichen.at(i))
return true;
}
return false;
}
void zerlegeText(ListenContainerT<string>* mLC,string text,string trennzeichen)
{
int wortbeginn = 0;
int wortende = 0;
for(int i=0;i<text.size();i++)
{
if( !istTrennzeichen(text.at(i),trennzeichen) )
{
wortbeginn = i;
while( i+1<text.size() && !istTrennzeichen(text.at(i+1),trennzeichen) )
i++;
wortende = i;
mLC->append(text.substr(wortbeginn,wortende-wortbeginn+1));
}
}
}
int main(void)
{
string text = "Das ist ein Text.";
string trennzeichen = ".,;: ";
ListenContainerT<string> mLC;
zerlegeText(&mLC,text,trennzeichen);
cout<<"GROESSE der Liste="<<mLC.getSize()<<endl;
for(int i=0;i<mLC.getSize();i++)
cout<<"Wort Nr."<<i<<":"<<mLC.get(i)<<endl;
ListenContainerT<double> zahlenliste;
cout<<"Geben Sie beliebig viele Zahlen ein. Beenden Sie die Eingabe mit quit ENTER."<<endl;
string eingabe;
cin>>eingabe;
while(eingabe!="quit")
{
zahlenliste.append(atof(eingabe.data()));
cin>>eingabe;
}
cout<<"Folgende Zahlen wurden eingegeben:"<<endl;
for(int i=0;i<zahlenliste.getSize();i++)
cout<<zahlenliste.get(i)<<", ";
}
Code 0-3: testetemplate.cpp
testetemplate.zip
Erläuterungen zur Verwendung von Schablonen/Templates in C++ anhand des obigen Beispiels
|