Template Problem
-
Hallo Leute,
bin dabei mich in c++ einzuarbeiten. Ich hänge gerade bei den Templates fest. Das von mir erstellte Programm soll einen Queue für variable Datentypen erzeugen. Einige Fumktionen zur Bearbeitung des Queue sind auch implementiert. Ich denke, der Algorithmus stimmt weitestgehend. Habe aber Probleme mit Syntax von Templates. Daher kann ich auch mit den (vielen) Fehlermeldungen meines Compilers wenig anfangen. Da ich echt nicht weiter weiss, hab ich eich mal den Quellcode gepostet. Kann mir da jemand weiterhelfen?
Besten Dank!#include <iostream.h> using namespace std; // Die Klasse Element dient als Datenobjekt, welches in der verketteten Liste // gespeichert wird. template <typename inhalt> class QueueElement { public: QueueElement(inhalt, inhalt*); ~QueueElement(); void show(); private: inhalt value; QueueElement *next; }; template <typename inhalt> QueueElement::QueueElement<inhalt> (inhalt &val, inhalt *nextE) { value = val; next = nextE } QueueElement::~QueueElement() {} void QueueElement::show() { cout << value << endl; } class Queue { public: Queue() {} ~Queue() {} template <typename ueber> void insert(ueber); template <typename rueck, typename ueber> rueck push_back(ueber); template <typename rueck> rueck get_front(); void remove_front(); private: QueueElement element; QueueElement *fuss; QueueElement *kopf; }; template <typename ueber> void Queue::insert(ueber value) { if (*kopf == 0) { kopf = QueueElement::QueueElement(value, 0); fuss = *kopf; } else kopf = QueueElement::QueueElement(value, kopf); } template <typename rueck, typename ueber> rueck Queue::push_back(ueber value) { if (*kopf == 0) { cout << "Der Queue ist noch leer!" << endl; return 0; } else if (*kopf->next == 0) { rueck temp = kopf->value; *kopf = QueueElement::QueueElement(value, 0); return temp; } // der Zeiger auf das vorletzte Objekt der Queue wird ermittelt else { QueueElement *speicher = *kopf->next; for(int i=0; *speicher->next->next != 0; ++i) { speicher = speicher->next; } rueck temp = speicher->value; speicher->next = 0; kopf = QueueElement::QueueElement(value, kopf); return temp; } } template <typename rueck> rueck Queue::get_front() { QueueElement *speicher = *kopf->next; for(int i=0; *speicher->next != 0; ++i) { speicher = speicher->next; } return speicher->value; } void Queue::remove_front() { QueueElement *speicher = *kopf->next; for(int i=0; *speicher->next->next != 0; ++i) { speicher = speicher->next; } speicher->next = 0; } int main() { Queue que; que.insert(10); cout<< que.push_back("abc") << endl; return 0; }
-
erstmal fallen mir beim Konstruktor schonmal zwei falsche Type auf:
//... public: QueueElement(inhalt, inhalt*); //... template <typename inhalt> QueueElement::QueueElement<inhalt> (inhalt &val, inhalt *nextE) { value = val; next = nextE }Das erste Argument ist in der Deklaration eine variable, in der Definition aber eine Referenz.
dann ist next in der Klassendefinition als pointer auf QueueElement feklariert, netE ist aber ein Pointer auf inhalt.Zur Template-geschichte: afaik müsste die Zeile mit der Definition folgendermaßen aussehen:
QueueElement<inhalt>::QueueElement (inhalt &val, inhalt *nextE) // ^--hier musses hin! ^--hier muss es nicht unbedingt hinähnliches bei allen anderen Methodendefinitionen.
Des weiteren hast du in der Klassendefinition einen zeiger auf QueueElement deklariert. Die Klasse gibt es so aber nicht, es gibt eben nur QueueElement<T> (wobei T eine beliebige Klasse ist). Hier gibts also einen argen Fehler im Aufbau.. Mehr dazu später.
In der Klassendefinition von Queue fehlen die Semikola hinter der Definition von Ctor und Dtor.
Dann bringst du in Queue::insert die Zeiger völlig durcheinander:
template <typename ueber> void Queue::insert(ueber value) { if (*kopf == 0) //du dereferenzierst hier kopf. Das heißt, du überprüfst, ob ein QueueElement 0 ist. Lass den * weg { kopf = QueueElement::QueueElement(value, 0); //kopf ist ein zeiger! Hier sollte ein "new QueueElement<ueber>(value, 0)" hin fuss = *kopf; //fuss ist auch ein zeiger! dahe kopf nicht dereferenzieren! } else kopf = QueueElement::QueueElement(value, kopf); //siehe oben }Soviel vorerst.
Schau dir dochmal bitte deine Zeigerakrobatik nochmal genauer an, das müsste auch aus den fehlermeldungen des compilers ersichtlich sein, dass das ein hauptproblem ist
-
Danke erstmal für die Antwort. Hab da jetzt denk ich alles soweit hinbekommen, aber noch einen etwas komischen Fehler. Und zwar gibt mir der Compiler folgenden Fehler:
In member function
void Queue::get_front()':show' has not been declared
request for member of non-aggregate type before '(' tokenUnd für remove_front() das selbe ...
Ich will das er show() von QueueElement aufruft, was ja über das virtual passieren müsste, oder?
Es soll ja ein Zeiger der Oberklasse verwendet werden um Konflikte mit Templates zu vermeiden ...Hier noch der Code:
#include <iostream> using namespace std; class QueElement { public: QueElement *next; virtual void show(); }; void QueElement::show() { cout<< "XXX" << endl; } // Die Klasse Element dient als Datenobjekt, welches in der verketteten Liste // gespeichert wird. template <typename inhalt=int> class QueueElement : public QueElement { public: QueueElement<inhalt>(inhalt, QueElement*); void show(); private: inhalt value; }; template <typename inhalt> QueueElement<inhalt>::QueueElement (inhalt val=0, QueElement *nextE=NULL) { value = val; next = nextE; } //QueueElement::~QueueElement() {} template <typename inhalt> void QueueElement<inhalt>::show() { cout<< "Push_Back: " << value << endl; } class Queue { public: Queue() { kopf = NULL; fuss = NULL; zeiger = kopf; }; ~Queue() {}; template <typename ueber> void push_back(ueber); void get_front(); void remove_front(); private: QueueElement<> element; QueElement *zeiger; QueElement *fuss; QueElement *kopf; }; template <typename ueber> void Queue::push_back(ueber value) { cout<< "Push_Back: " << value << endl; if (kopf == NULL) { kopf = new QueueElement<ueber>(value, NULL); fuss = kopf; } else if (kopf != NULL) { kopf = new QueueElement<ueber>(value, kopf); } } void Queue::get_front() { cout << "Get_Front: " << fuss.show() << endl; } void Queue::remove_front() { cout<< "Remove_Front: " << fuss.show() << endl; zeiger = kopf; for(int i=0; zeiger != fuss; ++i) zeiger = zeiger->next; zeiger->next = NULL; fuss = zeiger; } int main() { Queue que; que.push_back(7); que.push_back(9); que.push_back("Hallo"); que.get_front(); que.remove_front(); que.get_front(); que.remove_front(); que.get_front(); system("Pause"); return 0; }
-
fuss->show()
-
Danke

Hat etwas gedauert bis ich meinen eigentlichen Fehler hatte, weil das mit dem -> hatte ich schon gefunden ... man sollte nicht versuchen den Rückgabewert einer void-Methode auszugeben ;-P
Am Rande ... gibts eine andere GUTE Entwicklungsumgebung außer Dev-C++ ???
-
carnage schrieb:
Am Rande ... gibts eine andere GUTE Entwicklungsumgebung außer Dev-C++ ???
Nein !

Schau mal im "Andere Compiler" - forum. Da werden auch alternative IDE's diskutuert. Als tipp würde ich zu Mingw-Studio raten, wenns kostenlos sein soll, ansonsten kosten viele IDEs halt ein bisschen was. Wie gesagt, schau dich da mal um.