Template erstellen



  • hallo, ich hab versucht mir ein Template für eine einfache verkettete Liste zu erstellen. Das Template soll dabei aus 3 Klassen bestehen. Liste, Knoten und Iterator. Aber wenn ich das kompiliere werden zig fehler geworfen, u.a. "das Liste kein template sein".

    Hier mal mein Code (sind 3 klassen in einer, ist was viel, sieth jeamnd wo das template probleme hat)

    #include <iostream>
    
    template <typename T>
    class Knoten
    {
     public:
       Knoten();
       Knoten(<T> val);
       ~Knoten();
       <T> getVal();
       Knoten * getNext();  
       void addToNext(<T> val);      
    
     private:
       <T> m_iVal;
       Knoten * m_next;
    };
    
    Knoten::Knoten( ):m_next(0)
    {
    }
    
    Knoten::Knoten(<T> val):m_iVal(val),m_next(0)
    {
      std::cout<<"Konstruktor Knoten für Wert:"<<m_iVal<<std::endl;
    }
    
    Knoten::~Knoten()
    {
         std::cout<<"Destruktor Knoten für Wert:"<<m_iVal<<std::endl;
    }
    
    Knoten * Knoten::getNext()
    {
       return   m_next;
    }
    
    void Knoten::addToNext(<T> val)
    {
       if(m_next == 0)
           m_next = new Knoten(val);
       else
           m_next->addToNext(val);
    }
    
    <T> Knoten::getVal() { return m_iVal;}
    
    class Iterator
    {
      public:
         Iterator(Knoten * start);
         void inkrement();
         Knoten * getCurrentNode(){return m_iterator;}
        ~Iterator();
    
      private:
         Knoten * m_iterator;
    };
    
    Iterator::Iterator(Knoten * start)
    {
      m_iterator = start;
    }
    
    void Iterator::inkrement()
    {
       if (m_iterator->getNext() != 0)
         m_iterator = m_iterator->getNext();
    }
    
    class Liste
    {
      public:
         Liste();
        ~Liste();
         void add(<T> val);
         Iterator * createIter();
         Iterator * getIter() {return m_iterator;}
    
      private:
         void addToNext(<T> val);
         Knoten * m_first;
         Iterator * m_iterator;
    };
    
    Liste::Liste()
    {
      m_first = 0;
      m_iterator = 0;
    }
    
    Liste::~Liste()
    {
       Knoten * cur_node=0;
       Knoten * del_node =0;
    
       while (m_first != 0)
       {
        del_node = m_first;
        m_first = m_first->getNext();
        delete del_node;
       }
    
       if (m_first != 0)
           delete m_first;
    
    }
    
    void Liste::add(<T> val)
    {
       if (m_first == 0)
           m_first = new Knoten(val);
       else
           m_first->addToNext(val);
    }
    
    Iterator * Liste::createIter()
    {
       m_iterator = new Iterator(m_first);
       return m_iterator;
    }
    


  • Hallo Jimki,

    Warum benutz du die templateparammeter so <T>,
    du schreibst einfach T

    Willkommen aus der Javawelt 😃



  • Du darfst keine spitzen Klammern um den Template-Paramater machen:

    template <typename T>
    class Knoten
    {
    public:
       Knoten();
       Knoten(T val); // statt <T>
       ~Knoten();
       T getVal();
       Knoten * getNext();  
       void addToNext(T val);      
    
    private:
       T m_iVal;
       Knoten * m_next;
    };
    

    Iterator und Liste verwenden das Template "Knoten" ohne den Datentyp anzugeben.
    Entweder machst Du die auch zu Templates oder gibst einen konkreten Datentyp für Knoten an.



  • ok danke.

    Die fehler sind deutlich weniger geworden. Ich habe die Klassen Liste und Iterator ebenfalls mit einem <template T> ergänzt. Er meckert aber immernoch das Knoten

    In file included from main.cpp:1:
    Template.cpp:19: Fehler: »template<class T> class Knoten« ohne Template-Parameter verwendet
    Template.cpp:19: Fehler: ISO-C++ verbietet Deklaration von »Knoten« ohne Typ
    Template.cpp: In function »int Knoten()«:
    Template.cpp:19: Fehler: »int Knoten()« als andere Symbolart redeklariert
    Template.cpp:4: Fehler: vorherige Deklaration von »template<class T> class Knoten«
    Template.cpp:19: Fehler: nur Konstruktoren nehmen Basisinitialisierungen
    Template.cpp: At global scope:
    Template.cpp:23: Fehler: »template<class T> class Knoten« ohne Template-Parameter verwendet
    Template.cpp:23: Fehler: expected constructor, destructor, or type conversion before »(« token
    Template.cpp:28: Fehler: expected constructor, destructor, or type conversion before »::« token
    Template.cpp:33: Fehler: expected constructor, destructor, or type conversion before »*« token
    Template.cpp:38: Fehler: »template<class T> class Knoten« ohne Template-Parameter verwendet
    Template.cpp:38: Fehler: Variable oder Feld »addToNext« als »void« deklariert
    Template.cpp:38: Fehler: »T« wurde in diesem Gültigkeitsbereich nicht definiert
    Template.cpp:46: Fehler: »T« bezeichnet keinen Typ
    Template.cpp:48: Fehler: expected unqualified-id before »<« token

    hier mal ein geänderter code:

    Main

    #include "Template.cpp"
    #include <iostream>
    
    int main(int argc, char **argv)
    {
       Liste<int> a;
    
       return 0;
    }
    

    Template

    #include <iostream>
    
    template <typename T>
    class Knoten
    {
     public:
       Knoten();
       Knoten(T val);
       ~Knoten();
       T getVal();
       Knoten * getNext();  
       void addToNext(T val);      
    
     private:
       T m_iVal;
       Knoten * m_next;
    };
    
    Knoten::Knoten( ):m_next(0)
    {
    }
    
    Knoten::Knoten(T val):m_iVal(val),m_next(0)
    {
      std::cout<<"Konstruktor Knoten für Wert:"<<m_iVal<<std::endl;
    }
    
    Knoten::~Knoten()
    {
         std::cout<<"Destruktor Knoten für Wert:"<<m_iVal<<std::endl;
    }
    
    Knoten * Knoten::getNext()
    {
       return   m_next;
    }
    
    void Knoten::addToNext(T val)
    {
       if(m_next == 0)
           m_next = new Knoten(val);
       else
           m_next->addToNext(val);
    }
    
    T Knoten::getVal() { return m_iVal;}
    
    <template T>
    class Iterator
    {
      public:
         Iterator(Knoten * start);
         void inkrement();
         Knoten * getCurrentNode(){return m_iterator;}
        ~Iterator();
    
      private:
         Knoten * m_iterator;
    };
    
    Iterator::Iterator(Knoten * start)
    {
      m_iterator = start;
    }
    
    void Iterator::inkrement()
    {
       if (m_iterator->getNext() != 0)
         m_iterator = m_iterator->getNext();
    }
    
    <template T>
    class Liste
    {
      public:
         Liste();
        ~Liste();
         void add(T val);
         Iterator * createIter();
         Iterator * getIter() {return m_iterator;}
    
      private:
         void addToNext(T val);
         Knoten * m_first;
         Iterator * m_iterator;
    };
    
    Liste::Liste()
    {
      m_first = 0;
      m_iterator = 0;
    }
    
    Liste::~Liste()
    {
       Knoten * cur_node=0;
       Knoten * del_node =0;
    
       while (m_first != 0)
       {
        del_node = m_first;
        m_first = m_first->getNext();
        delete del_node;
       }
    
       if (m_first != 0)
           delete m_first;
    
    }
    
    void Liste::add(T val)
    {
       if (m_first == 0)
           m_first = new Knoten(val);
       else
           m_first->addToNext(val);
    }
    
    Iterator * Liste::createIter()
    {
       m_iterator = new Iterator(m_first);
       return m_iterator;
    }
    


  • Du solltest Dich wirklich vorher in die Template-Grundlagen einlesen. Woher hast Du diese <T> Syntax? Geraten? Trial&Error bringts nicht bei C++, glaub mir!

    Bei der Definition der Methoden musst Du dem Compiler natürlich auch sagen dass Du die Methodentemplates für das Template Knoten<T> und nicht für die Klasse Knoten (das sind zwei verschiedene Dinger!) definierst:

    template<typename T>
    Knoten<T>::Knoten(...)
    

Log in to reply