Klassentemplate Stack...problem mit größe des stacks dynamisch festlegen



  • Kann es sein das deine stackNode Klasse immer noch so aussieht ?

    template <typename T>
    class stackNode
    {
        ...
    };
    

    Wenn ja, dann mach das template weg. Immerhin brauch deine Node Klasse kein Template mehr, da sie jetzt in der Stack Klasse ist, wodurch ein Template bereits existiert.



  • muss mich entschuldigen hab den Fehler gefunden. 🙄
    War Fehler meinerseits, Programm läuft super danke dir FreakY<3Cpp
    Schönen abend noch Beste Grüße steve



  • Eine Frage hab ich noch.
    Bei dieser Methode:

    template <class T> int Stack::size() const
    	{
    	return counter;
    	}
    

    Kommte die Fehlermeldung:
    1>.\dua_u6.2.cpp(49) : error C2955: "stackNode": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich."

    Bitte ein letztes mal heut abend um hilfe 🙂



  • Richtig wäre

    template <typename T>
    int Stack<T>::size()
    {
        return counter;
    }
    

    Edit:
    Du musst dir aber auch mal gut die Fehlermeldungen durchlesen.
    Der Error sagt dir was mit einer template Argumentliste. Diese Argumentliste ist das was zwischen den <> steht. Das macht dir klar, dass da was fehlt.



  • genau das gleiche...
    die fehlermeldung hab ich davor übersehen:
    \dua_u6.2.cpp(73) : error C2244: 'Stack<T>::size': Keine Übereinstimmung für Funktionsdefinition mit vorhandener Deklaration gefunden



  • ne jut ok hab wieder ma was vergessen...
    🙄
    Ist glaube ich ein bissel zu spät...
    ich verabschiede mich 🙂
    Danke nochma und nen scheenen abend noch
    gruß steve



  • Saß bis jetzt dran nur die eine Funktion Funzt nich.Will dort den wert ausgeben auf den der Zeiger verweißt.
    Das Prog sieht jetzt so aus....

    // dua_u6.2.cpp: Hauptprojektdatei.
    
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    #ifndef _STACK_H
    #define _STACK_H
    
    template <class T> 
    class Stack 
    	{
    
    public:
    	//Konstruktor,setzt counter auf 0
    	Stack(): counter(0), topp(0){}		// Konstruktor (realisiert create() )
    	~Stack(){}							// Destruktor
    
      bool push(const T&);					//legt element auf stack ab, gibt wahr wenn erfolgreich
      void  pop();							//löscht das oberste element
      T& top() const;						//gibt oberstes element zurück
      bool isEmpty() const;					//testet ob stack leer ist
      int size() const;						//liefert aktuelle anzahl der elemente auf dem stack
    
    private:								//hier wurde die klasse stackNode mit in die klasse Stack eingefügt, der Übersicht halber, die Funktionen bleiben erhalten
    	class stackNode
    		{
    		public:
    			T data;
    			stackNode *next_element;
    		};
    	stackNode *topp;						// Zeiger auf Kopf des Stacks
    	int counter;							// Anzahl Elemente im Stack
    
         };
    
    //pusht element auf stack und gibt war wenn erfolgreich
    template <class T> bool Stack<T>::push(const T& to_pushing_data)
    	{
    	stackNode *node = new stackNode;
    	node->data = to_pushing_data;
    	node->next_element = topp;
    	topp = node;
    	++counter;
    	return true;
    	}
    
    //prüft ob Stack leer ist(0 Stack ist nicht leer und 1 Stack ist leer)
    template <class T> bool Stack<T>::isEmpty()const
    	{
    
    	if(counter == 0)
    		 return true;
    	else
    		return false;
    	}
    
    //gibt die größe des Stackes an
    template <class T> int Stack<T>::size()const
    	{
    	return counter;
    	}
    
    //löscht das oberste element
    template <class T> void Stack<T>::pop()
    	{
    	topp = topp->next_element;
    	counter--;
    	}
    
    template <class T> T& Stack<T>::top()const        !!!!!!!!!!!!!!!!!!!!!!
    	{                                        hier merkert der compiler
    	                                         !!!!!!!!!!!!!!!!!!!!!!!!!!
    	return *topp;
    	}
    
    #endif
    
    int main()
    {
    //Test mit double und string 
    
    //double Stack und string Stack definiert
    
    Stack<double> doubleStack;
    Stack<string> stringStack;
    
    //Stack fuellen mit 5 double elementen und 1 string element
    
    //DOUBLE
    cout << "DOUBLE" << endl<<endl;
    for(double index = 1.101023 ; index <=4 ; index++)
    	{
    	if(doubleStack.push(index))
    	cout << index << " " << "Double-Wert auf Stack abgelegt" <<endl;
    	else 
    		cout << "Konnte nicht abgelegt werden" <<endl;
    	}
    
    cout << "Oberstes Element:  " << doubleStack.top() << endl;
    cout << endl<<endl<<endl;
    
    //STRING
    cout << "STRING" <<endl<<endl;
    string text = "Hallo";
    
    	if(stringStack.push(text))
    	cout << "String" << "'" << text <<"'" << "auf Stack abgelegt"<<endl;
    	else 
    	cout << "Konnte nicht abgelegt werden" <<endl;
    
    cout << "Oberstes Element:  "   << stringStack.top() <<endl;
    
    }
    

    Gruß steve



  • Erstmal wäre es gut wenn du sagen würdest welche Funktion.
    Der Codestil ist immer noch recht unangenehm zu lesen.

    So aber nun zu deinem Problem.

    template <class T> 
    T& Stack<T>::top()const
    {
        return *topp;
    }
    

    Denk mal nach, was genau machst du hier ? Du gibst das GANZE Objekt an die Main zurück. Was bringt dir das? Du kannst das Objekt nicht an cout übergeben. Cout erwartet einen Wert, den es ausgeben kann. Jedoch dein Objekt enthält eine ganze Klasse. Du kannst nicht von cout erwarten eine Klasse auf die Konsole darzustellen. Wie soll es das auch tun ? Was du auf die Konsole schreiben willst, ist den Wert selbst. Da topp ein Objekt von stackNode enthält, kannst du auf stackNode->data zugreifen. Denn in der Variable data, die in stackNode beinhaltet ist, ist den Wert den wir brauchen.

    template <class T> 
    T& Stack<T>::top()const
    {
        return topp->data;
    }
    

    Edit:
    Glaub mir, solltest du so einen Codestil deinem Chef vorzeigen, lacht er dich aus und gibt dir den neuen Job als Putze.

    Denk dran noch einen Destruktor zu bauen. Du hast ihn zwar in der Klasse, jedoch macht er nichts. Du musst durch die Liste und jedes Objekt löschen.

    Edit2:
    Ich hab grad noch bemerkt, dass deine Pop Methode fast richtig ist, aber etwas entscheidenes fehlt.
    Durch pop, gehst du zwar auf das vorherige Element, löschst aber nicht das alte.

    template <class T>
    void Stack<T>::pop()
    {
        stackNode* old_element = topp;
        topp = topp->next_element;
        delete old_element;
        --counter;
    }
    

    Und hier noch der Destruktor

    template <class T>
    Stack<T>::~Stack()
    {
        while(topp)
        {
            stackNode* old_element = topp;
            topp = topp->next_element;
            delete old_element;
        }
    }
    

    Fast wie die Pop Methode, nur das nunmal alles gelöscht wird 😉
    Solltest du noch ne Frage haben, ich bin noch ne weile online 😛



  • Ich sag ma so aus Fehlern lernt man.Und ich hab hier ne Menge gelernt 🙂
    Hab die Aufgabe hab ich jetzt komplett bewältig natürlich mit deiner hilfe.
    Werde deine Verbesserungsvorschläge auf jedenFall beachten und an mir und meinen Stil arbeiten 😉 .

    Mit Freundlichem Gruß
    Steve



  • Der Destruktor wird aber eigtl immer so hier implementiert:

    while (!empty())
     pop();
    

    wenn du den code mal vergleichst wirst du nämlich sehen, dass du so das pop und das empty noch mal abgetippt hast - und man versucht ja immer so wenig code wie möglich zu duplizieren (idR schafft man es, ohne Code zu duplizieren ^^)

    bb


Anmelden zum Antworten