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
Erläuterungen zur Verwendung von Schablonen/Templates in C++ anhand des obigen Beispiels
|