Undefined Reference



  • So sieht Dictionary.h aus:

    #ifndef DICTIONARY_H_INCLUDED
    #define DICTIONARY_H_INCLUDED
    
    #include "Dictionary.h"
    #include <string>
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    template<class KEY, class VALUE>
    class DictionaryEntry
    {
        private:
            KEY m_key;
            VALUE m_value;
        public:
            DictionaryEntry();
            ...
    };
    
    template<class KEY, class VALUE, class KEY_COMPARATOR>
    class DictionaryEntryComparator
    {
        private:
            KEY_COMPARATOR m_comp;
        public:
            bool LessThan(const DictionaryEntry<KEY,VALUE>&,const DictionaryEntry<KEY,VALUE>&);
            bool IsEqual(const DictionaryEntry<KEY,VALUE>&,const DictionaryEntry<KEY,VALUE>&);
    };
    
    template<class KEY, class VALUE, class KEY_COMPARATOR=DefaultComparator<KEY> >
    class Dictionary
    {
        protected:
            SortedArray<DictionaryEntry<KEY,VALUE>,DictionaryEntryComparator<KEY,VALUE,KEY_COMPARATOR> > m_data;
        public:
            void Insert(const KEY&,const VALUE&);
            ...
    };
    
    #endif
    

    So sieht Dictionary.cpp aus:

    #include "Dictionary.cpp"
    
    template<class KEY, class VALUE>
    DictionaryEntry<KEY,VALUE>::DictionaryEntry(){}
    ...
    template<class KEY, class VALUE, class KEY_COMPARATOR>
    bool DictionaryEntryComparator<KEY, VALUE, KEY_COMPARATOR>::LessThan(const DictionaryEntry<KEY,VALUE>& a,const DictionaryEntry<KEY,VALUE>& b)
    {
        return m_comp.LessThan(a.GetKey(),b.GetKey());
    }
    
    template<class KEY, class VALUE, class KEY_COMPARATOR>
    bool DictionaryEntryComparator<KEY, VALUE, KEY_COMPARATOR>::IsEqual(const DictionaryEntry<KEY,VALUE>& a,const DictionaryEntry<KEY,VALUE>& b)
    {
        return m_comp.IsEqual(a.GetKey(),b.GetKey());
    }
    ...
    template<class KEY, class VALUE, class KEY_COMPARATOR>
    void Dictionary<KEY, VALUE, KEY_COMPARATOR>::Insert(const KEY& key,const VALUE& value)
    {
        m_data.Insert(DictionaryEntry<KEY,VALUE>(key,value));
    }
    ...
    


  • GuardianOfLife schrieb:

    Sry, die Defintion steht natürlich in der Header-Datei.

    Jaja... 🙄

    GuardianOfLife schrieb:

    So sieht Dictionary.cpp aus:

    template<class KEY, class VALUE>
    DictionaryEntry<KEY,VALUE>::DictionaryEntry(){}
    


  • Und was haben Nexus und ich oben geschrieben?
    Template ALLES in den header. Auch Definition (!=Deklaration)



  • Eben das kann ich nicht schreiben.
    Dictionary<int,int> dict; <- denn da kommt der ganz oben beschriebene Fehler.



  • Bitte reiss dich etwas zusammen und lies den Thread nochmals.



  • Wie soll ich die Templates ausschließlich im Header haben? Dann kann ich die Methoden nicht implementieren.



  • GuardianOfLife schrieb:

    Wie soll ich die Templates ausschließlich im Header haben? Dann kann ich die Methoden nicht implementieren.

    Glaubst du, wir erzählen dir hier absichtlich Schwachsinn?

    Du musst Templates in Headern implementieren. Wieso sollte das nicht gehen?



  • K ich glaub ich habs gecheckt aber dann brauch ich ja die cpp datein nicht mehr, oder?



  • Lesen bildet:

    undefined reference to DictionaryEntry<int, int>::DictionaryEntry()
    

    Du hast den Konstruktor von DictionaryEntry zwar deklariert, aber nicht definiert. Oder uns Code unterschlagen...



  • GuardianOfLife schrieb:

    K ich glaub ich habs gecheckt aber dann brauch ich ja die cpp datein nicht mehr, oder?

    Na endlich ist der Groschen gefallen....... 😃



  • GuardianOfLife schrieb:

    K ich glaub ich habs gecheckt aber dann brauch ich ja die cpp datein nicht mehr, oder?

    Nein, brauchst du bei Templates nicht. Was du aber machen kannst, ist eine .inl-Headerdatei, die du am Ende der eigentlichen Headerdatei einbindest und in die du wie bei einer .cpp-Datei deine Funktionen definierst. So hast du trotzdem noch Trennung zwischen Schnittstelle und Implementierung.

    jencas schrieb:

    Du hast den Konstruktor von DictionaryEntry zwar deklariert, aber nicht definiert. Oder uns Code unterschlagen...

    Nein, er hat ihn schon definiert, allerdings in der .cpp-Datei.



  • Was ich aber nicht kapieren, ist das bei einem anderen Projekt, in dem ich die selben Dateien benutzt habe, alles wunderbar funktioniert hat, seltsam 😕



  • Wahrscheinlich hast du dort das Template nicht instanziiert.



  • Doch, aber egal, jetzt funktioniert alles normal. Danke für die Hilfe. 🙂



  • Nexus schrieb:

    jencas schrieb:

    Du hast den Konstruktor von DictionaryEntry zwar deklariert, aber nicht definiert. Oder uns Code unterschlagen...

    Nein, er hat ihn schon definiert, allerdings in der .cpp-Datei.

    Ooops, hab ich tatsächlich übersehen... Du hast natürlich Recht.



  • Sry, die Überschriften bei Dictionary haben nicht gestimmt hab es verbessert, und ich hatte DictionaryEntry definiert(hab es au so gepostet), aber das ist nicht länger wichtig.



  • jencas schrieb:

    Ooops, hab ich tatsächlich übersehen... Du hast natürlich Recht.

    Den übersieht man noch schnell mal, wenn die ganze Implementierung nur aus {} besteht... 😉



  • ^^



  • Nexus schrieb:

    jencas schrieb:

    Ooops, hab ich tatsächlich übersehen... Du hast natürlich Recht.

    Den übersieht man noch schnell mal, wenn die ganze Implementierung nur aus {} besteht... 😉

    ...ja, und den Quellcode sooooooooooooo übersichtlich gliedert 😉


Anmelden zum Antworten